分析:
割顶练手题
注意输入就好了
(第一个数是结点编号,剩下的一行里是与之向连的点的编号)
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=110;
int n;
struct node{
int x,y,nxt;
};
node way[N*N*2];
int st[N],tot=0,pre[N],low[N],clo,ans;
bool iscut[N];
void add(int u,int w)
{
tot++;
way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;
tot++;
way[tot].x=w;way[tot].y=u;way[tot].nxt=st[w];st[w]=tot;
}
void in(int x)
{
int t=0;
char ch;
ch=getchar(); ch=getchar();
while (ch!='\n')
{
if (ch==' '){
add(x,t);
t=0;
ch=getchar();
continue;
}
t=t*10+ch-'0';
ch=getchar();
}
add(x,t);
return;
}
void dfs(int u,int fa)
{
int ch=0;
int lowu=pre[u]=++clo;
for (int i=st[u];i;i=way[i].nxt)
{
int v=way[i].y;
if (!pre[v])
{
ch++;
dfs(v,u);
lowu=min(lowu,low[v]);
if (low[v]>=pre[u]) {
if (!iscut[u]) ans++;
iscut[u]=1; //存在即合理
}
}
else if (v!=fa)
{
lowu=min(lowu,pre[v]);
}
}
if (fa==-1&&ch==1) {
if (iscut[u]) ans--;
iscut[u]=0;
}
low[u]=lowu;
}
int main()
{
while (scanf("%d",&n)!=EOF&&n)
{
memset(st,0,sizeof(st)); tot=0;
memset(pre,0,sizeof(pre)); clo=0;
memset(iscut,0,sizeof(iscut));
ans=0;
int x,y;
while (scanf("%d",&x)!=EOF&&x)
in(x);
for (int i=1;i<=n;i++)
if (!pre[i])
dfs(i,-1);
printf("%d\n",ans);
}
return 0;
}