vector<int> G[maxn];
int pre[maxn], low[maxn], c[maxn];
int n, m;
stack<int> s;
int dfstime, scc_cnt;
void dfs(int u, int fa){
pre[u] = low[u] = ++dfstime;
int len = G[u].size();
s.push(u);
for (int i = 0; i < len; i++){
int v = G[u][i];
if (pre[v] == -1){
dfs(v, u);
low[u] = min(low[u], low[v]);
}
/*else if (low[v] < pre[u] && v != fa){///双连通里面,这里是通过反向边更新的
low[u] = min(low[u], low[v]);
}*/
else if (!c[v]){///下面为什么是pre[v]而不是low[v](两者都可以)
low[u] = min(low[u], pre[v]);///因为环装最后总会变回来,一样的
}
}
if (low[u] == pre[u]){
scc_cnt++;
while (true){
int x = s.top(); s.pop();
c[x] = scc_cnt;
if (x == u) break;
}
}
return ;
}