제출 #1251140

#제출 시각아이디문제언어결과실행 시간메모리
1251140minhpkOne-Way Streets (CEOI17_oneway)C++20
100 / 100
173 ms44368 KiB
#include <bits/stdc++.h>
using namespace std;

int a, b;
vector<pair<int,int>> z[100005];
pair<int,int> edge[100005];

int id[100005], low[100005];
int cnt = 0;
int check[100005];

bool vis[100005];

int ver = 0;
int par[100005], sz[100005];
int mark[100005];

struct node {
    int x, id, flip;
};
vector<node> z1[100005];

pair<int,int> rev[100005];
int ans[100005];

int high[100005];
int up[100005][25];
int xuoi[100005], ngc[100005];
int sta[100005], fin[100005], tour = 0;

unordered_map<long long,int> m;

long long hash_pair(int x, int y) {
    return 1LL * x * 1000000 + y; 
}

void dfs(int i, int parent) {
    cnt++;
    id[i] = low[i] = cnt;
    for (auto p : z[i]) {
        int nxt = p.first, eId = p.second;
        if(nxt == parent) continue;
        if(id[nxt])
            low[i] = min(low[i], id[nxt]);
        else {
            dfs(nxt, i);
            low[i] = min(low[i], low[nxt]);
            if(low[nxt] >= id[i])
                check[eId] = 1;
        }
    }
}

int find(int u) {
    return (par[u] == u ? u : par[u] = find(par[u]));
}
void join(int x, int y) {
    x = find(x);
    y = find(y);
    if(x == y) return;
    if(sz[x] < sz[y]) swap(x, y);
    sz[x] += sz[y];
    par[y] = x;
}

void predfs(int i, int parent) {
    tour++;
    sta[i] = tour;
    up[i][0] = parent;
    for (auto p : z1[i]) {
        if(p.x == parent) continue;
        high[p.x] = high[i] + 1;
        rev[p.x] = {p.id, p.flip};
        predfs(p.x, i);
    }
    fin[i] = tour;
}

int lca(int x, int y) {
    if(high[x] < high[y]) swap(x, y);
    for (int i = 20; i >= 0; i--) {
        if(high[ up[x][i] ] >= high[y])
            x = up[x][i];
    }
    if (x==y) return x;
    for (int i = 20; i >= 0; i--) {
        if(up[x][i] != up[y][i] && up[x][i] != 0) {
            x = up[x][i];
            y = up[y][i];
        }
    }
    return up[x][0];
}

void dfs1(int i, int parent) {
    for (auto p : z1[i]) {
        if(p.x == parent) continue;
        dfs1(p.x, i);
        xuoi[i] += xuoi[p.x];
        ngc[i] += ngc[p.x];
        if (xuoi[p.x] > 0 && m[hash_pair(i, p.x)] <= 1)
            ans[rev[p.x].first] = 1 * rev[p.x].second;
        if (ngc[p.x] > 0 && m[hash_pair(i, p.x)] <= 1)
            ans[rev[p.x].first] = -1 * rev[p.x].second;
    }
}

signed main(){
    if (fopen("oneway.inp","r")){
        freopen("oneway.inp","r",stdin);
        freopen("oneway.out","w",stdout);
    }
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> a >> b;
    for (int i = 1; i <= b; i++){
        int x, y;
        cin >> x >> y;
        z[x].push_back({y, i});
        z[y].push_back({x, i});
        edge[i] = {x, y};
    }

    for (int i = 1; i <= a; i++){
        if(!id[i])
            dfs(i, 0);
    }

    for (int i = 1; i <= a; i++){
        par[i] = i;
        sz[i] = 1;
    }
    for (int i = 1; i <= b; i++){
        if(!check[i])
            join(edge[i].first, edge[i].second);
    }

    for (int i = 1; i <= a; i++){
        int x = find(i);
        if(!vis[x]){
            vis[x] = true;
            ver++;
            mark[x] = ver;
        }
        mark[i] = mark[x];
    }

    for (int i = 1; i <= b; i++){
        int x = mark[ edge[i].first ];
        int y = mark[ edge[i].second ];
        if(x == y) continue;
        z1[x].push_back({y, i, 1});
        z1[y].push_back({x, i, -1});
        m[hash_pair(x,y)]++;
        m[hash_pair(y,x)]++;
    }

    high[0] = -1;
    for (int i = 1; i <= ver; i++){
        if(sta[i] == 0){
            high[i] = 0;
            predfs(i, 0);
        }
    }

    for (int j = 1; j <= 20; j++){
        for (int i = 1; i <= ver; i++){
            int parNode = up[i][j-1];
            if(parNode == 0)
                up[i][j] = 0;
            else
                up[i][j] = up[ parNode ][j-1];
        }
    }

    int q;
    cin >> q;
    for (int i = 1; i <= q; i++){
        int x, y;
        cin >> x >> y;
        x = mark[x];
        y = mark[y];
        if (x==y) continue;
        int l = lca(x, y);
        xuoi[x]++;
        xuoi[l]--;
        ngc[y]++;
        ngc[l]--;
    }

    for (int i = 1; i <= ver; i++){
        if(up[i][0] == 0) {
            dfs1(i, 0);
        }
    }

    for (int i = 1; i <= b; i++){
        if(ans[i] == 0)
            cout << "B";
        else if(ans[i] < 0)
            cout << "R";
        else
            cout << "L";
    }

    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

oneway.cpp: In function 'int main()':
oneway.cpp:110:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  110 |         freopen("oneway.inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
oneway.cpp:111:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  111 |         freopen("oneway.out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...