CDOJ1208 作为求双连通分量的模板

本文介绍了一个使用C++实现的算法,该算法用于寻找无向图中的所有桥和割点,并通过双连通分量的概念来确定这些特殊元素。文中详细展示了如何通过深度优先搜索(DFS)来标记并分析图的连接性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// Note:Your choice is C++ IDE
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define min(a,b)  ((a)>(b)?(b):(a))
typedef struct sldfj
{
	int u;
	int v;
	int next;
}Edge;
const int mmax=10050;
Edge edge[mmax*20];
int dfsnum[mmax],low[mmax],Time,Enum,root,n,m,head[mmax],top;
int stack[mmax*100];
int ans1,ans2;
bool vis[mmax];
void add(int u,int v)
{
	edge[Enum].u=u;
	edge[Enum].v=v;
	edge[Enum].next=head[u];
	head[u]=Enum++;
}
void insert(int u,int v)
{
	add(u,v);
	add(v,u);
} 
void dfs(int u,int fa)
{
	dfsnum[u]=low[u]=++Time;
	for(int i=head[u];i!=-1;i=edge[i].next)
	{
		int v=edge[i].v;
		if(v!=fa&&dfsnum[v]<dfsnum[u])
		{
			stack[top++]=i;
			if(dfsnum[v]<0)
			{
				dfs(v,u);
				low[u]=min(low[u],low[v]);
				if(low[v]>=dfsnum[u])//割点
				{
					int dnum=0,bnum=0,e,s,t;
					memset(vis,0,sizeof(vis));
					do{//下面退出来的边和点是一个双连通分量
						 e=stack[--top];
						 s=edge[e].u;
						 t=edge[e].v;
						 bnum++;
						 if(!vis[s])
						 {
					 		dnum++;
					 		vis[s]=1;
						 }
						 if(!vis[t])
						 {
					 		dnum++;
					 		vis[t]=1;
						 }		 
					}while(e!=i);
					if(dnum<bnum)
						ans2+=bnum;
				}
				if(low[v]>dfsnum[u])//桥
					ans1++;
			}
			else low[u]=min(low[u],dfsnum[v]);
		}
	}
}
int main()
{
    while(scanf("%d%d",&n,&m))
    {
    	int i;
		if(!n&&!m)break;
    	Enum=0;
    	memset(head,-1,sizeof(head));
    	for(i=0;i<m;i++)
    	{
    		int a,b;
    		scanf("%d%d",&a,&b);
    		insert(a,b);
    	}
    	Time=0;
    	top=0;
    	ans1=ans2=0;
		memset(dfsnum,-1,sizeof(dfsnum));
		for(i=0;i<n;i++)
    		if(dfsnum[i]<0)dfs(i,-1);
    	printf("%d %d\n",ans1,ans2);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值