loj2480 [CEOI2017]One-Way Streets 边双+树上差分
边双无法确定
缩完边双就是一棵树
树上差分随意弄一下吧...
#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> namespace remoon { #define re register #define de double #define le long double #define ri register int #define ll long long #define sh short #define pii pair<int, int> #define mp make_pair #define pb push_back #define tpr template <typename ra> #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++) #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --) extern inline char gc() { static char RR[23456], *S = RR + 23333, *T = RR + 23333; if(S == T) fread(RR, 1, 23333, stdin), S = RR; return *S ++; } inline int read() { int p = 0, w = 1; char c = gc(); while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); } while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc(); return p * w; } int wr[50], rw; #define pc(iw) putchar(iw) tpr inline void write(ra o, char c = '\n') { if(!o) pc('0'); if(o < 0) o = -o, pc('-'); while(o) wr[++ rw] = o % 10, o /= 10; while(rw) pc(wr[rw --] + '0'); pc(c); } tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; } tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; } tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; } } using namespace std; using namespace remoon; #define sid 500050 int n, m, cnp = 1, tim, top, bcc; int id[sid], jg[sid], U[sid], V[sid], dfn[sid], low[sid], st[sid]; int nxt[sid], node[sid], cap[sid], bel[sid]; inline void addedge(int u, int v, int w = 0) { id[cnp + 1] = id[cnp + 2] = w; nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v; nxt[++ cnp] = cap[v]; cap[v] = cnp; node[cnp] = u; } #define cur node[i] inline void tarjan(int o, int fa) { st[++ top] = o; dfn[o] = low[o] = ++ tim; for(int i = cap[o]; i; i = nxt[i]) if(!dfn[cur]) { tarjan(cur, i), cmin(low[o], low[cur]); if(low[cur] <= dfn[o]) continue; int p; ++ bcc; while(p != cur) bel[p = st[top --]] = bcc; } else if((i ^ 1) != fa) cmin(low[o], dfn[cur]); } int eg[sid], vis[sid], up[sid], down[sid]; int son[sid], sz[sid], dep[sid], anc[sid], fa[sid]; inline void dfs(int o) { sz[o] = 1; for(int i = cap[o]; i; i = nxt[i]) if(cur != fa[o]) { eg[id[i]] = cur; fa[cur] = o; dep[cur] = dep[o] + 1; dfs(cur); sz[o] += sz[cur]; if(sz[son[o]] < sz[cur]) son[o] = cur; } } inline void dfs(int o, int ac) { anc[o] = ac; if(!son[o]) return; dfs(son[o], ac); for(int i = cap[o]; i; i = nxt[i]) if(cur != fa[o] && cur != son[o]) dfs(cur, cur); } inline int lca(int u, int v) { int pu = anc[u], pv = anc[v]; while(pu != pv) { if(dep[pu] < dep[pv]) swap(pu, pv), swap(u, v); u = fa[pu]; pu = anc[u]; } return (dep[u] < dep[v]) ? u : v; } inline void cot(int o) { vis[o] = 1; for(int i = cap[o]; i; i = nxt[i]) if(cur != fa[o]) cot(cur), up[o] += up[cur], down[o] += down[cur]; } int main() { n = read(); m = read(); rep(i, 1, m) { U[i] = read(); V[i] = read(); addedge(U[i], V[i]); } rep(i, 1, n) if(!dfn[i]) { tarjan(i, 0); ++ bcc; while(top) bel[st[top --]] = bcc; } cnp = 1; memset(cap, 0, sizeof(cap)); rep(i, 1, m) { int u = U[i], v = V[i]; if(bel[u] == bel[v]) jg[i] = 1; else addedge(bel[u], bel[v], i); } rep(i, 1, bcc) if(!dep[i]) dfs(i), dfs(i, i); int q = read(); rep(i, 1, q) { int x = read(), y = read(); if(bel[x] == bel[y]) continue; else { int lc = lca(bel[x], bel[y]); up[bel[x]] ++; up[lc] --; down[bel[y]] ++; down[lc] --; } } rep(i, 1, bcc) if(!vis[i]) cot(i); rep(i, 1, m) { int u = bel[U[i]], v = bel[V[i]]; if(jg[i] == 1) printf("%c", 'B'); else { if(dep[u] < dep[v]) { if(up[eg[i]]) printf("%c", 'L'); else if(down[eg[i]]) printf("%c", 'R'); else printf("%c", 'B'); } else { if(up[eg[i]]) printf("%c", 'R'); else if(down[eg[i]]) printf("%c", 'L'); else printf("%c", 'B'); } } } return 0; }
喵喵喵?喵喵喵! 喵喵喵......