讲解博客:
https://blog.youkuaiyun.com/WhereIsHeroFrom/article/details/79417926
这篇文章讲解的很详细了! 懒得写
int dfn[N],low[N],colnum,color[N],top,st[N],vis[N];
/* dfn 表示dfs序
low 当前结点能追溯到祖先dfn数最小的值
colnum 强连通染色总数
color 每个强连通颜色
st 数组模拟栈 top栈顶序号 vis是否在栈中
*/
void tarjan(int x)
{
low[x]=dfn[x]=++cnt;//一开始都为序号
vis[x]=1;
st[++top]=x;//当前点放入栈中
for(int to:v[x])//遍历该点邻边
{
if(!dfn[to])//如果未访问过,就访问
{
tarjan(to);
low[x]=min(low[x],low[to]);//更新low
}
else if(vis[to]) low[x]=min(low[x],dfn[to]);//如果目标点已在栈中,目标dfn与自身low取最小
}
if(low[x]==dfn[x])
//如果找完该点所有邻边,并且dfs序列与low相同,那么栈顶到x的所有元素均在同一个强连通分量之内,弹出所有元素并染色
{
vis[x]=0;
color[x]=++colnum;
while(st[top]!=x)
{
color[st[top]]=colnum;
vis[st[top--]]=0;
}
top--;
}
}