#482. 单一故障点

【题目描述】:

2 2
/ \ /
1—3 1 3
/ \ | |
4—5 4—5
拿左边的图举例,有一个计算机网络,在这个网络只能是点对点双向通信,如果3号节点出故障了,那么1号节点与2号节点,4号节点和5号节点还是可以通信的,不过1,2号不能和4,5号节点通信了。这样3号节点就是一个SPF节点,并且当3号节点出故障了分为了2个子网络。

注意右边的网络没有这样的节点;网络没有SPF。至少要2台机器出现故障才可能会有节点不能进行通信。

找到图中的SPF,并输出删除某个SPF点之后,可以将图分为几块

【输入描述】:

输入包含若干网络描述。一个网络的描述将包括若干整数对。每行一对,确定连接的节点,连接是无向的。所有节点将从1开始小于等于1000。边数不超过2500。一行包含一个单一的零结束一个图的描述,后面跟着一个空行。最终以一个0,结束所有输入。

【输出描述】:

对于每个网络。你将输出图的编号,然后列出所有SPF节点。

文件中的第一个网络应认定为“Network #1”。依次第二个是“Network #2”,单独成行。每个图中每个SPF节点,输出一行,格式如下面的例子所示,输出节点号和将图分成不连通分量的数量。如果网络没有SPF的节点,只需输出文本“ No SPF nodes”。

【样例输入】:

1 2
5 4
3 1
3 2
3 4
3 5
0

1 2
2 3
3 4
4 5
5 1
0

1 2
2 3
3 4
4 6
6 3
2 5
5 1
0

0

【样例输出】:

Network #1
  SPF node 3 leaves 2 subnets

Network #2
  No SPF nodes

Network #3
  SPF node 2 leaves 2 subnets
  SPF node 3 leaves 2 subnets

【时间限制、数据范围及描述】:

时间:1s 空间:64M

【AC代码】:

#include<bits/stdc++.h>
#define M(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
using namespace std;
inline void read(int &x){
    char ch=getchar(),c=ch;
	x=0;
    while(ch<'0' || ch>'9'){
    	 c=ch;
		 ch=getchar();
	}
    while(ch>='0' && ch<='9'){
    	x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
    if(c=='-')x=-x;
} 


const int MAXN=1005;
const int MAXM=5005;

struct Node{
	int v,next;
}edge[5005];
int ans[MAXN];
int p[1005],n,m,dfn[1005],low[5005],ec,san,cTime;

void add(int u, int v){	 
    edge[++ec].v = v;
    edge[ec].next = p[u];
    p[u] = ec;
}

void clea(){
	memset(p,0,sizeof(p));
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	for(int i=1;i<=5000;i++)
		edge[i].v=edge[i].next=0;
	for(int i=1;i<=1000;i++)
		ans[i]=0;
	printf("Network #%d\n",n);
}

void Tarjan(int u,int fa){
    dfn[u]=low[u]=++cTime;int cnt=0;
    for(int i=p[u];i;i=edge[i].next){	
        int v=edge[i].v;if(v==fa) continue;
        if(!dfn[v]){cnt++;
            Tarjan(v,u);low[u]=min(low[u],low[v]);
			if((low[v]>=dfn[u] && u!=1)||(u==1 && cnt>1))
				{ans[u]++;san++;}
		}
		else low[u]=min(low[u],dfn[v]);
    }
}

int main(){
	int x,y;
	while(1){
		scanf("%d",&x);
		if(x==0)break;
		n++;
		clea();
		ec=0;
		cTime=0;
		while(1){
			read(y);
			add(x,y);
			add(y,x);
			read(x);
			if(x==0)break;
		}san=0;
		for(int i=1;i<=n;i++)if(dfn[i]==0)Tarjan(i,0);
		if(san==0)printf("  No SPF nodes\n");
		for(int i=1;i<=1000;i++)
			if(ans[i]>0)
			printf("  SPF node %d leaves %d subnets\n",i,ans[i]+1);
		printf("\n");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值