int Stack[maxn], low[maxn], dfn[maxn], inStack[maxn], belong[maxn]; int now, cnt; // now:时间戳,cnt强连通的个数 vector<int> g[maxn]; stack<int> s; void init() { now = cnt = 0; memset(inStack, 0,sizeof(inStack)); memset(belong, 0,sizeof(belong)); memset(dfn, 0,sizeof(dfn)); memset(low, 0,sizeof(low)); for(int i=0;i<maxn;i++) g[i].clear(); } void tarjan(int u) { // 打上标记,入栈 low[u] = dfn[u] = ++now; s.push(u); inStack[u] = 1; for (int i = 0; i < (int)g[u].size(); ++i) { int v = g[u][i]; if (!dfn[v]) { //未访问过 tarjan(v); low[u] = min(low[u], low[v]); //low,dfn(v)中可能是最小的 } else if (inStack[v]) { //访问过,还在栈中 low[u] = min(low[u], dfn[v]); //dfn (v)中找最小 } } // 回溯,如果当前节点的dfn = low 表示栈中形成一个强连通分量 if (dfn[u] == low[u]) { ++cnt; // 统计个数 int v=-1; while (v!= u) { v = s.top(); s.pop(); belong[v] = cnt; inStack[v] = 0; } } } for(int i=1;i<=n;i++){ // 因为是有向图 从一个点出发也行不能把整个图跑完 ,所以需要多次 if(!dfn[i]) tarjan(i); }