POJ1523 SPF (无向图求割点)

题目大意:给出一个无向图,求每个割点,并且输出每个割点能把图分成多少个部分


思路:裸的求割点的题目。割点是指在连通图中的一个点,删除这个点后,连通图的各个部分不再连通。

注:此题输入巨坑,注意格式

#include<cstdio>
#include<cstring>
#define MAXN 1010
#define Min(a,b) a<b?a:b
using namespace std;
struct E
{
	int v;
	int next;
}edge[MAXN*10];
int cnt;
int head[MAXN];
void add_edge(int u,int v)
{
	edge[cnt].v = v;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
int low[MAXN];//
int dfn[MAXN];//访问顺序
int cutp[MAXN];//保存割点能分成的连通块数
int dcnt;//dfs数(访问顺序)
void dfs(int u,int fa)
{
	low[u] = dfn[u] = ++dcnt;//low[u]初始化
	int tt = 0;//根节点儿子个数
	for(int i = head[u]; i != -1; i = edge[i].next)
	{
		int v = edge[i].v;
		if(!dfn[v])//未访问过v,(u,v)为树边
		{
			dfs(v,u);
			low[u] = Min(low[u],low[v]);
			if(low[v] >= dfn[u])
			{
				if(fa != -1) cutp[u]++;
				else tt++;
			}
		}
		else if(v != fa)
			low[u] = Min(low[u],dfn[v]);
	}
	if(fa == -1&&tt >= 2)//根节点特判
		cutp[1] = tt;
}
int main()
{
	int a,b;
	int t = 0;
	while(scanf("%d",&a) != EOF&&a)
	{
		scanf("%d",&b);
		memset(head,-1,sizeof(head));
		memset(low,0,sizeof(low));
		memset(dfn,0,sizeof(dfn));
		memset(edge,0,sizeof(edge));
		memset(cutp,0,sizeof(cutp));
		cnt = 0;
		dcnt = 0;
		add_edge(a,b);
		add_edge(b,a);
		while(scanf("%d",&a) != EOF&&a)
		{
			scanf("%d",&b);
			add_edge(a,b);
			add_edge(b,a);
		}
		dfs(1,-1);
		bool flag = 0;
		printf("Network #%d\n",++t);
		for(int i = 1; i <=dcnt ; i++)
			if(cutp[i])
			{
				printf("  SPF node %d leaves %d subnets\n",i,cutp[i] + (i != 1));//输出时加1(在计数的时候没有记录该割点父亲的连通块)
				flag = 1;
			}
		if(!flag)
			printf("  No SPF nodes\n");
		printf("\n");
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值