【模板】【POJ1144】Network——tarjan求割点

题目链接

题目大意:

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()!='\n'){
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\n",ss);
43         scanf("%d",&n);
44     }
45     return 0;
46 }
POJ1144

 

posted @ 2017-11-09 10:09  Child-Single  阅读(193)  评论(0编辑  收藏  举报