Network

题目描述:

A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N . No two places have the same number. The lines are bidirectional and always connect together two places and in each place the lines end in a telephone exchange. There is one telephone exchange in each place. From each place it is

possible to reach through lines every other place, however it need not be a direct connection, it can go through several exchanges. From time to time the power supply fails at a place and then the exchange does not operate. The officials from TLC realized that in such a case it can happen that besides the fact that the place with the failure is unreachable, this can also cause that some other places cannot connect to each other. In such a case we will say the place (where the failure

occured) is critical. Now the officials are trying to write a program for finding the number of all such critical places. Help them.
给定多张无向图,求出每张图中割点数量

输入:

多组数据

每组数据第一行一个n,当n=0时输入结束

后面不超过n行,每行第一个数x,当x=0时该组数据结束

x后面一列数a,ai表示x与ai间有一条无向边

(若原图中有边a-b,则保证输入中至少会在a后面有b或者在b后面有a

输出:

每组数据输出图中割点数目

样例输入:

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

样例输出:

1
2

code:

糟心的输入。。。。看了半天也没有看懂到底是什么意思。。。。
总的来说,就是求割点的数量

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn=1500;
int n;
int cnt=0;
bool cut[maxn];
int head[maxn];
int visit[maxn];
int dfn[maxn];
int low[maxn];
struct node{
	int to,next;
}edge[maxn*2];
void add(int u,int v)
{
	edge[cnt].to=v;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}
void bridge(int what,int father,int dep)
{
	visit[what]=1;
	dfn[what]=low[what]=dep;
	int child=0;
	for(int i=head[what];i!=-1;i=edge[i].next)
	{
		int x=edge[i].to;
		if(visit[x]==1)
		{
			low[what]=min(dfn[x],low[what]);
		}
		if(visit[x]==0)
		{
			bridge(x,what,dep+1);
			child++;
			low[what]=min(low[what],low[x]);
			if((father==-1&&child>1)||(father!=-1&&low[x]>=dfn[what]))
				cut[what]=1;
		}
	}
	visit[what]=2;
}
int main()
{
	while(~scanf("%d",&n)&&n)
	{
		cnt=0;
		memset(edge,0,sizeof(edge));
		memset(cut,0,sizeof(cut));
		memset(head,-1,sizeof(head));
		memset(visit,0,sizeof(visit));
		memset(dfn,0,sizeof(dfn));
		memset(low,0,sizeof(low));
		int u;
		scanf("%d",&u);
		while(u)
		{
			int v;
			while(getchar()!='\n')
			{
				scanf("%d",&v);
				add(u,v);
				add(v,u);
			}
			scanf("%d",&u);
		}
		for(int i=1;i<=n;i++)
		{
			if(visit[i]==0)
			{
				bridge(i,-1,0);
			}
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			if(cut[i])ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}
        
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值