zoukankan      html  css  js  c++  java
  • 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 = '
    ') {
            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;
    }
  • 相关阅读:
    设计模式之桥接模式
    设计模式之适配器模式
    设计模式之建造者模式
    设计模式之原型设计
    Exception in thread "main" java.lang.UnsupportedOperationException
    设计模式7大原则
    设计模式之单例模式
    初识python
    消息传递:发布订阅模式详解
    哨兵机制(Redis Sentinel)
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9773657.html
Copyright © 2011-2022 走看看