void tarjan(int u) { int v; dfn[u] = low[u] = ++cnt;//开始时dfn[u] == low[u] S[top++] = u;//进栈 vis[u] = true; for (int i=head[u]; i!=-1; i=Edge[i].next) { v = Edge[i].to; if (dfn[v] == 0)//如果v点还未遍历 { tarjan(v);//向下遍历 low[u] = low[u] < low[v] ? low[u] : low[v];//确保low[u]最小 } else if (vis[v] && low[u] > dfn[v])//v在栈中,修改low[u] low[u] = dfn[v]; } if (dfn[u] == low[u])//u为该强连通分量中遍历所成树的根 { ++scc; do { v = S[--top];//栈中所有到u的点都属于该强连通分量,退栈 vis[v] = false; belong[v] = scc; } while (u != v); } }
可通过如下题目巩固:
poj2186
poj2553
poj1236
hdu1269
hdu4280
poj1273
poj2112
poj3469