const int maxn = 10010; int dfn[maxn]; //第i个点被dfs到次序 int low[maxn]; //二叉搜索树上i所在子数上仍在栈中的最小dfn,low[i]相等的点在一个强连通分量中 bool vis[maxn]; stack<int>s; vector<int>to[maxn]; int tot; int res[maxn]; //储存强连通分量,res[i]表示点i属于第res[i]个强连通分量 int num[maxn]; //第i个强连通分量的点数 void tarjan(int x) { dfn[x] = low[x] = ++cnt; s.push(x); vis[x] = true; for (int i = 0; i < to[x].size(); i++) { if (!dfn[to[x][i]]) { tarjan(to[x][i]); low[x] = min(low[x], low[to[x][i]]); } else if (vis[to[x][i]]) { low[x] = min(low[x], dfn[to[x][i]]); } } if (low[x] == dfn[x]) { tot++; while (!s.empty() && s.top() != x) { int t = s.top(); res[t] = tot; num[tot]++; vis[t] = false; s.pop(); }; s.pop(); res[x] = tot; num[tot]++; vis[x] = false; } }