POJ 1523 SPF

求去点割点后,能把图分成几个块。

若u为割点,记cnt[u]为u的子节点数,则去掉u后,图被分成cnt[u]+1个部分(每个子节点的部分和u的祖先的部分),若u为dfs树的根,则分成cnt[u]个部分(根节点没有祖先)


#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<vector>

using namespace std;

const int inf=0x7ffffff;
const double PI=acos(-1.0);
const double eps=1e-8;
bool map[1010][1010];
int low[1010];
int dfn[1010];
bool vis[1010];
int cnt[1010];
int depth,n,son;

void init()
{
	memset(map,0,sizeof(map));	
	memset(vis,0,sizeof(vis));
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	memset(cnt,0,sizeof(cnt));
}

void dfs(int v)
{
	dfn[v]=depth;
	low[v]=depth++;
	vis[v]=true;
	for(int i=1;i<=n;i++)	
		if(map[v][i])
		{	
			if(!vis[i])
			{
				dfs(i);
				low[v]=min(low[i],low[v]);
				if(low[i]>=dfn[v] && v!=1)
					cnt[v]++;
				else if(v==1) son++;
			}
			else low[v]=min(low[v],dfn[i]);
		}
}
int main()
{
	int a,b,cas=1,c,d;
	while(~scanf("%d",&a),a)
	{
		scanf("%d",&b);
		n=max(a,b);
		init();
		map[a][b]=map[b][a]=1;
		while(1)
		{
			scanf("%d",&c);
			if(c==0) break;
			scanf("%d",&d);
			map[c][d]=map[d][c]=1;
			n=max(n,c);
			n=max(n,d);
		}
		son=0;
		depth=1;
		dfs(1);
		bool flag=false;
		if(son>1)
			cnt[1]=son-1;
		printf("Network #%d\n",cas++);
		for(int i=1;i<=n;i++)
			if(cnt[i])	
			{
				flag=1;
				printf("  SPF node %d leaves %d subnets\n",i,cnt[i]+1);	
			}
		if(!flag) puts("  No SPF nodes");
		puts("");
	}
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值