Network UVA - 315 无向图找割点
题意:
给你一个无向图,你需要找出来其中有几个割点
割点/割项:
1、u不为搜索起点,low[v]>=dfn[u]
2、u为搜索起点,size[ch]>=2
3、一般情况下,不建议在tarjan中直接输出答案(可能会有重复)
4、在有重边的情况下,将tarjan传值中的father改为其编号,由于存边的连续性
只要判断 (当前编号)i != (father编号)pre^1
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int maxn=105; 8 int cnt,head[maxn],n,dfn[maxn],low[maxn],num,qua,root,iscut[maxn]; 9 struct edge 10 { 11 int u,v,next; 12 }e[maxn*maxn]; 13 void add_edge(int x,int y) 14 { 15 e[cnt].u=x; 16 e[cnt].v=y; 17 e[cnt].next=head[x]; 18 head[x]=cnt++; 19 } 20 void tarjan(int x) 21 { 22 dfn[x]=low[x]=++num; 23 int flag=0; 24 for(int i=head[x];i!=-1;i=e[i].next) 25 { 26 int to=e[i].v; 27 if(!dfn[to]) 28 { 29 tarjan(to); 30 low[x]=min(low[x],low[to]); 31 if(low[to]>=dfn[x]) 32 { 33 flag++; 34 if(x!=root || flag>1) iscut[x]=1,qua++; 35 } //一个割点可能会多次经历iscut[x]=1,所以qua里面的值不是割点数目 36 } 37 else low[x]=min(dfn[to],low[x]); 38 } 39 } 40 int main() 41 { 42 while(~scanf("%d",&n) && n) 43 { 44 cnt=num=qua=0; 45 memset(iscut,0,sizeof(iscut)); 46 memset(head,-1,sizeof(head)); 47 memset(dfn,0,sizeof(dfn)); 48 memset(low,0,sizeof(low)); 49 int x,y; 50 char ch; 51 while(~scanf("%d",&x) && x) 52 { 53 while(~scanf("%d",&y)) 54 { 55 scanf("%c",&ch); 56 add_edge(x,y); 57 add_edge(y,x); 58 if(ch=='\n'){ 59 break; 60 } 61 } 62 } 63 // for(int i=0;i<cnt;++i) 64 // { 65 // printf("%d %d\n",e[i].u,e[i].v); 66 // 67 // } 68 for(int i=1;i<=n;++i) 69 { 70 if(!dfn[i]) 71 { 72 //printf("**\n"); 73 root=i; 74 tarjan(i); 75 } 76 } 77 int ans=0; 78 for(int i=1;i<=n;++i) 79 if(iscut[i]) ++ans; 80 printf("%d\n",ans); 81 } 82 return 0; 83 }