#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
vector <int> vec[110];
int dfn[110] , low[110],in[110];
int n, step , sum ;
void init()
{
for(int i=0;i<110;i++)
{
dfn[i]=low[i]=in[i]=0;
vec[i].clear();
}
step=sum=0;
}
void insert(int u , int v)
{
vec[u].push_back(v);
vec[v].push_back(u);
}
void tarjan(int u , int rt ,int fa)
{
int v ,son=0;
low[u]=dfn[u]=++step;
for(int i=0;i<vec[u].size();i++)
{
v=vec[u][i];
if(!dfn[v])
{
son++;
tarjan(v , rt ,u);
low[u]=min(low[u] , low[v]);
if(u==rt && son>1 || low[v]>=dfn[u] && u!=rt ) in[u]=1;
//之前我的判断写成了low[v]>=low[u],改的我都快死了。
}
else low[u]=min(low[u] , dfn[v]);
}
}
int main()
{
int a, b;
while(scanf("%d",&n)!=EOF && n)
{
init();
while(scanf("%d",&a) && a)
{
while(getchar()!='\n')
{
scanf("%d",&b);
insert(a , b);
}
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i ,i ,0);
}
}
for(int i=1;i<=n;i++)
if(in[i]) sum++;
printf("%d\n",sum);
}
return 0;
}
之前一直有个盲点,多亏这道裸的求割点: 若该点是割点, 则去掉这个点后,整个图的连通分支一定会增多。例如:
3
1 2
2 3
这个图中1点就不是割点,另外环中的点也不是割点。
另外,这道题导致一直wa的原因,若判断失误,则在存在环(环中的点>=3)时一定会出问题。例如:
6
1 2
2 3
3 4
4 5
5 6
6 3
这个图中递归到u=6时,停止递归 low[6] = 3 ,回到上一层 low[ 5 ] = min ( low[6] , low[5] ) = 3 ,后面判断 low[v] > = low[u]一定存在,所以就会将环中的点也算作割点,导致错误。