loj2480 [CEOI2017]One-Way Streets

Posted reverymoon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

 

以上是关于loj2480 [CEOI2017]One-Way Streets的主要内容,如果未能解决你的问题,请参考以下文章

@loj - 2483@「CEOI2017」Building Bridges

LOJ #3166. 「CEOI2019」魔法树

解题:CEOI 2017 Mousetrap

Luogu P4654 [CEOI2017]Mousetrap

Luogu P4654 [CEOI2017]Mousetrap

在 Custom TG2480H 打印机上打印徽标