51nod 1076

* 无向图的割边将图分为不连通的两部分
* 对于是否有不想交的两条路径将s -> t 相连
* 只需判断是否处于同一部分
* Tarjan即可

#include <bits/stdc++.h>

const int N = 25010;

int Low[N], Dfn[N], Bel[N], Stack[N], topp;
struct Node {int u, v, nxt;} G[(int)1e5 + 10];
int now, head[N];
int n, m;
bool vis[N];

#define gc getchar()

inline int read() {
    int x = 0; char c = gc;
    while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
    return  x;
}

inline void Add(int u, int v) {
    G[++ now].v = v; G[now].nxt = head[u]; head[u] = now;
}

int clo, Bel_;

void Tarjan(int u, int fa) {
    Low[u] = Dfn[u] = ++ clo;
    Stack[++ topp] = u; vis[u] = 1;
    for(int i = head[u]; ~ i; i = G[i].nxt) {
        int v = G[i].v;
        if(!Dfn[v]) {
            Tarjan(v, u);
            Low[u] = std:: min(Low[u], Low[v]);
        } else
            if(vis[v] && v != fa) Low[u] = std:: min(Low[u], Low[v]);
    }
    /*if(Low[u] == Dfn[u]) {
        ++ Bel_;
        while(Low[Stack[topp]] == Low[u]) {
            vis[Stack[topp]] = 0, Bel[Stack[topp]] = Bel_, topp --;
        }
    }*/
    if(Low[u] == Dfn[u]) {
        ++ Bel_;
        vis[u] = 0, Bel[u] = Bel_;
        while(Stack[topp] != u) {
            vis[Stack[topp]] = 0;
            Bel[Stack[topp]] = Bel_;
            topp --; 
        } topp --;
    }
}

int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; i ++) head[i] = -1;
    for(int i = 1; i <= m; i ++) {
        int u = read(), v = read();
        Add(u, v), Add(v, u);
    }
    for(int i = 1; i <= n; i ++) {
        if(!Dfn[i]) Tarjan(i, 0);
    }
    int Q = read();
    for(; Q; Q --) {
        int s = read(), t = read();
        if(Bel[s] == Bel[t]) puts("Yes");
        else puts("No"); 
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/shandongs1/p/9445237.html