tarjan[模板]

强连通分量(有向图)

void tarjan(int x)
{
	dfn[x]=low[x]=++cnt;
	stac[++top]=x;
	vis[x]=1;
	for(int i=hd[x];i;i=nxt[i])
	{
		int y=go[i];
		if(!dfn[y])//树边
		{tarjan(y);low[x]=min(low[x],low[y]);}
		else if(vis[y])low[x]=min(low[x],dfn[y]);//在栈中(判横叉边)
	}
	if(low[x]==dfn[x])//出不去
	{
	    col_cnt++;
	    while(stac[top+1]!=x){
	    	c[stac[top]]=col_cnt;
	    	vis[stac[top]]=0;
	    	ve[col_cnt].push_back(stac[top]);
	    	top--;
		}
	}
}

边双连通分量(无向图)

void tarjan(int u,int fa)
{
	dfn[u]=low[u]=++cnt;
	stac[++top]=u;
	int son=0;
	for(int i=hd[u];i;i=nxt[i])
	{
		int v=go[i];
		if(!dfn[v])
		{
			son++;
			tarjan(v,i);
			low[u]=min(low[v],low[u]);
		}
		else if(i!=(fa^1)) low[u]=min(low[u],dfn[v]);//可以通过重边走向父亲
	}
	if(low[u]==dfn[u])
	{
		++col;
		while(stac[top+1]!=u)
		{	
			ans[col].push_back(stac[top--]);
		}	
	}
	return ;
}

点双连通分量(无向图)

void tarjan(int u,int fa)
{
	dfn[u]=low[u]=++cnt;
	stac[++top]=u;
	int son=0;
	for(int i=hd[u];i;i=nxt[i])
	{
		int v=go[i];
		if(!dfn[v])
		{
			son++;
			tarjan(v,u);
			low[u]=min(low[v],low[u]);
			if(low[v]>=dfn[u])
			{
				++col;
				while(stac[top+1]!=v)
				{	
					ans[col].push_back(stac[top--]);
				}	
				ans[col].push_back(u);//因为一个割点可能属于多个点双,所以不能出栈
			}
		}
		else if(v!=fa) low[u]=min(low[u],dfn[v]);
	}
	if(fa==0&&son==0)ans[++col].push_back(u);//特判独立点
	return ;
}
posted @   storms11  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示