* 无向图的割边将图分为不连通的两部分
* 对于是否有不想交的两条路径将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; }