tarjan模板(带注释)


//dfsn[x]记录x节点有没有被访问过,有,则是第几个 
//lowlink[x]记录x能到的祖先中编号最小的
//dfs_clock是个编号累计器 
//scc记录一个 
inline void dfs_scc(int x)
{
	dfsn[x]=lowlink[x]=++dfs_clock;//访问次序标记;x能到的祖先中节点编号最小的 
	stack[++top]=x;//把走过的节点入栈 
	for(int i=0;i<e[x].size();i++)
	{
		int now=e[x][i].to;
		if(!dfsn[now])//如果没有被访问过 
		{
			dfs_scc(now);//进它 
			lowlink[x]=min(lowlink[x],lowlink[now]);//既然now是x的子节点,那么他们一定有公告的祖先,取个小的 
		} 
		else
		if(!scc[now])//如果他还没有被其他强连通分量使用 
		lowlink[x]=min(lowlink[x],dfsn[now]);//那么再小一点 
	}
	if(lowlink[x]==dfsn[x])
	{
		scc_cnt++;
		while(stack[top]!=x)//x节点在栈中夹着的节点就是强连通分量的节点 
		scc[stack[top--]]=scc_cnt;//哪一个点在当前编号为scc_cnt的强连通分量里 
		top--;
		scc[x]=scc_cnt;//一个强连通分量 
	} 
} 
posted @ 2019-07-24 19:34  ShineEternal  阅读(212)  评论(1编辑  收藏  举报