题目描述:
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;
}