题目大意:
n个点m条边的无向图,下面最多n行,每一行的第二到最后一个数与第一个数有边相连,保证图联通,求割点数。
分析:
典型的tarjan求割点,dfs出一棵树来就差不多了,读入的细节需要注意。
注意根节点若只有一个儿子则不是割点。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mem(a,p) memset(a,p,sizeof(a)) 5 const int N=105; 6 struct node{int ne,to;}e[100005]; 7 int n,first[N],tot=0,dfn[N],inscut[N],low[N],num=0; 8 void init(){ 9 mem(first,0);tot=0;num=0; 10 mem(dfn,0);mem(low,0);mem(inscut,0); 11 } 12 void ins(int u,int v){ 13 e[++tot].ne=first[u];e[tot].to=v;first[u]=tot; 14 } 15 void tarjan(int x,int fa){ 16 dfn[x]=++num;low[x]=num;int child=0; 17 for(int i=first[x];i;i=e[i].ne){ 18 int to=e[i].to; 19 if(!dfn[to]){ 20 child++; 21 tarjan(to,x); 22 if(low[to]<low[x])low[x]=low[to]; 23 if(low[to]>=dfn[x])inscut[x]=1; 24 } 25 else if(to!=fa&&dfn[to]<low[x])low[x]=dfn[to]; 26 } 27 if(x==1&&child==1)inscut[x]=0; 28 } 29 int main(){ 30 scanf("%d",&n); 31 while(n){ 32 init(); 33 int b,p; 34 while(scanf("%d",&p)&&p){ 35 while(getchar()!=' '){ 36 scanf("%d",&b);ins(p,b);ins(b,p); 37 } 38 } 39 tarjan(1,0);int ss=0; 40 for(int i=1;i<=n;i++) 41 if(inscut[i])ss++; 42 printf("%d ",ss); 43 scanf("%d",&n); 44 } 45 return 0; 46 }