树:n点 n-1边
基环树:n点 n以上边
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, M = N*2;
int n, q;
int h[N], e[M], ne[M], idx;
int fa[N], d[N];
void add (int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void topsort () {
queue <int> q;
for (int i = 1; i <= n; i++) {
if (d[i] == 1) q.push (i);
}
while (!q.empty()) {
int t = q.front();
q.pop ();
fa[t] = -1; //无环 因为度数为1
for (int i = h[t]; ~i; i = ne[i]) {
int j = e[i];
if (--d[j] == 1) q.push (j);
}
}
}
void dfs (int u, int v) {
fa[u] = v;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (fa[j] == -1) dfs (j, v);//如果是不在环上的点 就把一条链上的点都设置为在环上的点
}
}
int main () {
memset (h, -1, sizeof h);
cin >> n;
for (int i = 0; i < n; i++) {
int a, b;
cin >> a >> b;
add (a, b), add (b, a);
d[a] ++, d[b] ++;
}
//topsort找环 不在环上会标记成-1
topsort ();
for (int i = 1; i <= n; i++) {
if (fa[i] == 0) dfs (i, i);//剩下的就是在环上的了
}
cin >> q;
while (q --) {
int u, v;
cin >> u >> v;
if (fa[u] == fa[v]) cout << "Yes\n";
else cout << "No\n";
}
}
//dfs合并到环上
标签:基环,一个点,idx,fa,int,路径,++,add
From: https://www.cnblogs.com/liang302/p/16635629.html