//深度优先搜索生成数的根root是图G的割点,当且仅当,root至少有两个节点; //不是深度优先搜索生成树的根的节点v是图G的割点,当且仅当,v的所有后裔都没有后退边与v的祖先顶点相连 • #include<stdio.h> • #include<string.h> • #define SIZE 150 • #define MAX 0x7fffffff • int map[SIZE][SIZE]; • int n; • int low[SIZE];//low[u]表示从u出发经过其后代顶点形成的路径和一条回退边所能达到的具有最小深度优先 编号 • int tot[SIZE];//tot[u]表示u的子节点的个数 • int visited[SIZE];//标记是否访问 • int dep[SIZE];//dep[u]表示节点u的深度优先编号 • int cute[SIZE];//标记是否为割点 • int min(int i,int j) • { • return(i>j?j:i); • } • void init()//输入图 • { • int temp; • int i; • int j; • memset(map,0,sizeof(map)); • memset(visited,0,sizeof(visited)); • memset(cute,0,sizeof(cute)); • memset(tot,0,sizeof(tot)); • for(i=1;i<=n;i++) • { • low[i]=MAX; • } • • temp=1; • char c=getchar(); • scanf("%d",&temp); • while(temp!=0) • { • • while((c=getchar())!='/n') • { • scanf("%d",&j); • map[temp][j]=map[j][temp]=1; • } • scanf("%d",&temp); • } • } • void dfs(int k,int deep) • { • dep[k]=deep; • low[k]=deep; • visited[k]=1; • int i; • for(i=1;i<=n;i++) • { • if(map[k][i]) • { • if((visited[i]==1)) • { • low[k]=min(low[k],dep[i]); • } • if(visited[i]==0) • { • tot[k]++; • dfs(i,deep+1); • low[k]=min(low[k],low[i]); • if((k!=1)&&(low[i]>=dep[k]))//如果不是根节点 • { • cute[k]=1; • } • else if((k==1)&&(tot[k]>1))//如果是根节点,且其子节点的个数大于 1 • { • cute[k]=1; • } • } • } • } • • } • int main() • { • // freopen("in.txt","r",stdin); • int temp; • int i; • while((scanf("%d",&n)!=EOF)&&(n!=0)) • { • init(); • dfs(1,1); • temp=0; • for(i=1;i<=n;i++) • { • if(cute[i]) • { • temp++; • } • } • printf("%d/n",temp); • } • return 0; • }