标准的求割顶的问题,用tarjan算法,参见www.nocow.cn割点词条
/*
* poj1144 AC
* 求无向图割顶
* tarjan算法,好好背一背!
* */
#include<memory.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
struct NODE{
int v,next;
}edge[20020];
long tot,head[105];
int n,ans,dfn[105],low[105],sons,ind;
int tarjan(int x)
{
int i;
bool mark = false;
dfn[x] = low[x] = ++ind;
i = head[x];
while(i)
{
if(!dfn[edge[i].v])
{
if(x==1) sons++;
tarjan(edge[i].v);
low[x] = min(low[x],low[edge[i].v]);
if(x!=1 && low[edge[i].v]>=dfn[x]) /*这个判断一定在这个if语句中!!要判断x是否等于1*/
mark = true;
}else
low[x] = min(low[x],dfn[edge[i].v]);
i = edge[i].next;
}
if(mark) ans++;
return ans;
}
int main()
{
// FILE* fin;
int j,k;
char c;
// fin = fopen("d.in","r");
while(scanf("%d",&n) && n)
{
memset(edge,0,sizeof(edge));
memset(head,0,sizeof(head));
tot = sons = ans = ind = 0;
while(scanf("%d",&j) && j)
{
while((c=getchar())!='\n')
{
scanf("%d",&k);
edge[++tot].v = k;
edge[tot].next = head[j];
head[j] = tot;
edge[++tot].v = j;
edge[tot].next = head[k];
head[k] = tot;
}
}
int sum = 0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
sum = tarjan(1);
if(sons>1) sum++;
printf("%d\n",sum);
}
return 0;
}