poj 3352 Road Construction(边双连通分量+缩点)
题目链接:http://poj.org/problem?id=3352
这题和poj 3177 一样,参考http://www.cnblogs.com/frog112111/p/3367039.html
AC代码:
1 #include<cstdio> 2 #include<cstring> 3 const int N=5000+5; 4 const int M=10000+5; 5 6 struct EDGE 7 { 8 int v,next; 9 }edge[M*2]; 10 int first[N],low[N],dfn[N],belong[N],degree[N],sta[M],instack[M]; 11 int g,cnt,top,scc; 12 int min(int a,int b) 13 { 14 return a<b?a:b; 15 } 16 void AddEdge(int u,int v) 17 { 18 edge[g].v=v; 19 edge[g].next=first[u]; 20 first[u]=g++; 21 } 22 void Tarjan(int u,int fa) 23 { 24 int i,v; 25 low[u]=dfn[u]=++cnt; 26 sta[++top]=u; 27 instack[u]=1; 28 for(i=first[u];i!=-1;i=edge[i].next) 29 { 30 v=edge[i].v; 31 if(i==(fa^1)) 32 continue; 33 if(!dfn[v]) 34 { 35 Tarjan(v,i); 36 low[u]=min(low[u],low[v]); 37 } 38 else if(instack[v]) 39 low[u]=min(low[u],dfn[v]); 40 } 41 if(dfn[u]==low[u]) 42 { 43 scc++; 44 while(1) 45 { 46 v=sta[top--]; 47 instack[v]=0; 48 belong[v]=scc; 49 if(v==u) 50 break; 51 } 52 } 53 } 54 int main() 55 { 56 int n,m,u,v,i,j; 57 scanf("%d%d",&n,&m); 58 g=cnt=top=scc=0; 59 memset(first,-1,sizeof(first)); 60 memset(low,0,sizeof(low)); 61 memset(dfn,0,sizeof(dfn)); 62 memset(instack,0,sizeof(instack)); 63 memset(degree,0,sizeof(degree)); 64 for(i=0;i<m;i++) 65 { 66 scanf("%d%d",&u,&v); 67 { 68 AddEdge(u,v); 69 AddEdge(v,u); 70 } 71 } 72 for(i=1;i<=n;i++) 73 if(!dfn[i]) 74 Tarjan(1,-1); 75 for(i=1;i<=n;i++) 76 { 77 for(j=first[i];j!=-1;j=edge[j].next) 78 { 79 v=edge[j].v; 80 if(belong[i]!=belong[v]) 81 degree[belong[i]]++; 82 } 83 } 84 int sum=0; 85 for(i=1;i<=n;i++) 86 if(degree[i]==1) 87 sum++; 88 int ans=(sum+1)/2; 89 printf("%d\n",ans); 90 return 0; 91 }
posted on 2013-10-13 23:35 jumpingfrog0 阅读(328) 评论(0) 编辑 收藏 举报