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 }
View Code

 

posted on 2013-10-13 23:35  jumpingfrog0  阅读(328)  评论(0编辑  收藏  举报

导航