【图论】简单环
stack<int> S;
vector<int> circle;
int dep[100005];
void dfs(int u, int p, int d) {
dep[u] = d;
if(!circle.empty())
return;
//printf("u=%d\n", u);
vis[u] = 1;
S.push(u);
int latestA = 0;
for(int v : G[u]) {
if(vis[v] == 2)
continue;
if(v == p)
continue;
if(vis[v] == 1) {
if(latestA == 0 || dep[v] > dep[latestA])
latestA = v;
}
}
if(latestA) {
while(vis[latestA] == 1) {
assert(S.size());
circle.push_back(S.top());
vis[S.top()] = 2;
S.pop();
}
return;
}
for(int v : G[u]) {
if(v == p)
continue;
if(vis[v]) {
assert(vis[v] == 2);
continue;
}
dfs(v, u, d + 1);
}
if(!S.empty())
S.pop();
vis[u] = 2;
}
利用dfs的性质,每个点先遍历看看是否有反向边,若有反向边则记录最近的祖先。