제출 #619522

#제출 시각아이디문제언어결과실행 시간메모리
619522czhang2718One-Way Streets (CEOI17_oneway)C++17
100 / 100
243 ms35512 KiB
#include "bits/stdc++.h"
using namespace std;

#define rep(i,a,b) for(int i=a; i<=b; i++)
#define sz(x) int(x.size())

const int N=1e5+1, K=18;
int n, m, q;
vector<int> adj[N], adj2[N];
int edge[N][2];
bool vis[N];
bool bridge[N];
int par[N];
set<int> s[N];
char dir[N];
int p[N][K];
int h[N];

void dfs(int x, int prv){
    // e = prv edge
    vis[x]=1;
    for(int e:adj[x]){
        if(e==prv) continue;
        int k=edge[e][0]==x?edge[e][1]:edge[e][0];
        if(vis[k]) s[x].insert(k);
    }
    for(int e:adj[x]){
        if(e==prv) continue;
        int k=edge[e][0]==x?edge[e][1]:edge[e][0];
        if(vis[k]) continue;
        dfs(k, e);
        if(sz(s[k])>sz(s[x])) swap(s[x], s[k]);
        for(int u:s[k]) s[x].insert(u);
    }
    s[x].erase(x);
    // cout << "s[" << x << "]\n";
    // for(int t:s[x]) cout << t << " ";
    //     cout << "\n";
    if(!sz(s[x]) && prv) bridge[prv]=1;
}

int find(int x){ return par[x]==x?x:par[x]=find(par[x]); }
void join(int x, int y){ par[find(x)]=find(y); }

void dfs2(int x){
    vis[x]=1;
    for(int e:adj[x]){
        int k=edge[e][0]==x?edge[e][1]:edge[e][0];
        if(!bridge[e] && !vis[k]){
            join(x,k);
            dfs2(k);
        }
    }
}

void dfs3(int x){
    vis[x]=1;
    rep(i,1,K-1) p[x][i]=p[p[x][i-1]][i-1];
    for(int e:adj2[x]){
        int k=edge[e][0]==x?edge[e][1]:edge[e][0];
        if(vis[k]) continue;
        h[k]=h[x]+1;
        p[k][0]=x;
        // cout << "par " << k << " " << x << "\n";
        dfs3(k);
    }
}

int up[N], down[N];

void dfs4(int x, int prv){
    vis[x]=1;
    for(int e:adj2[x]){
        int k=edge[e][0]==x?edge[e][1]:edge[e][0];
        if(vis[k]) continue;
        p[k][0]=x;
        dfs4(k, e);
        up[x]+=up[k];
        down[x]+=down[k];
    }
    assert(!(up[x] && down[x]));
    if(prv){
        if(up[x]) dir[prv]=edge[prv][0]==x?'R':'L';
        if(down[x]) dir[prv]=edge[prv][1]==x?'R':'L';
    }
}

int lca(int u, int v){
    if(h[v]>h[u]) swap(u,v);
    int d=h[u]-h[v];
    rep(k,0,K-1){
        if(d&(1<<k)) u=p[u][k];
    }
    if(u==v) return u;
    for(int k=K-1; k>=0; k--){
        if(p[u][k] && p[u][k]!=p[v][k]){
            u=p[u][k];
            v=p[v][k];
        }
    }
    return p[u][0];
}

int main(){
    cin.tie(0)->sync_with_stdio(0);

    cin >> n >> m;
    rep(i,1,m){
        int u,v; cin >> u >> v;
        if(u==v){
            dir[i]='B'; continue;
        }
        edge[i][0]=u;
        edge[i][1]=v;
        dir[i]='B';
        adj[u].push_back(i);
        adj[v].push_back(i);
    }

    rep(i,1,n){
        par[i]=i;
        if(vis[i]) continue;
        dfs(i, 0);
    }
    rep(i,1,n) vis[i]=0;

    rep(i,1,n){
        if(vis[i]) continue;
        dfs2(i);
    }

    rep(e,1,m){
        // if(bridge[e]) cout << "bridge " << e << '\n';
        int a=find(edge[e][0]);
        int b=find(edge[e][1]);
        edge[e][0]=a;
        edge[e][1]=b;
        if(a!=b) adj2[a].push_back(e), adj2[b].push_back(e);
    }

    rep(i,1,n) vis[i]=0;
    rep(i,1,n){
        if(vis[i]) continue;
        dfs3(i);
    }

    cin >> q;
    while(q--){
        int u,v; cin >> u >> v;
        u=find(u);
        v=find(v);
        if(u==v) continue;
        int a=lca(u,v);
        up[u]++;
        up[a]--;
        down[v]++;
        down[a]--;
        // cout << u << " " << a << " " << v << "\n";
    }

    rep(i,1,n) vis[i]=0;
    rep(i,1,n){
        if(!vis[i]) dfs4(i, 0);
    }

    rep(i,1,m) cout << dir[i];
}
// find bridges
// tree
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...