POJ 3177 Redundant Paths(Tarjan)

题目链接

题意 : 一个无向连通图,最少添加几条边使其成为一个边连通分量 。

思路 :先用Tarjan缩点,缩点之后的图一定是一棵树,边连通度为1。然后找到所有叶子节点,即度数为1的节点的个数leaf,最后要添加的边的条数就是(leaf+1)/2 ;

 1 // 3177
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 using namespace std ;
 8 
 9 int head[101010],fb[101010],low[101010],dfn[101010] ,degree[101010];
10 int cnt,timee ,ans ;
11 struct node
12 {
13     int u ;
14     int v ;
15     int next ;
16 }p[101010];
17 
18 void tarjan(int u)
19 {
20     dfn[u] = low[u] = ++timee  ;
21     for(int i = head[u] ; i != -1 ; i = p[i].next)
22     {
23         int v = p[i].v ;
24         if(fb[i^1]) continue ;
25         fb[i] = 1 ;
26         if(dfn[v])  low[u] = min(low[u],dfn[v]) ;
27         else
28         {
29             tarjan(v) ;
30             low[u] = min(low[v],low[u]) ;
31             //if(low[v] > dfn[u])
32             //    ans /++ ;
33         }
34     }
35 }
36 void Init()
37 {
38     cnt = timee = ans = 0 ;
39     memset(head,-1,sizeof(head)) ;
40     memset(dfn,0,sizeof(dfn)) ;
41     memset(low,0,sizeof(low)) ;
42     memset(fb,0,sizeof(fb)) ;
43     memset(degree,0,sizeof(degree)) ;
44 }
45 void addedge(int u,int v)
46 {
47     p[cnt].u = u ;
48     p[cnt].v = v ;
49     p[cnt].next = head[u] ;
50     head[u] = cnt ++ ;
51     p[cnt].u = v ;
52     p[cnt].v = u ;
53     p[cnt].next = head[v] ;
54     head[v] = cnt ++ ;
55 }
56 int main()
57 {
58     int F,R ;
59     while(scanf("%d %d",&F,&R) != EOF)
60     {
61         Init() ;
62         int x,y ;
63         for(int i = 0 ; i < R ; i++)
64         {
65             scanf("%d %d",&x,&y) ;
66             addedge(x-1,y-1) ;
67         }
68         tarjan(0) ;
69         for(int i = 0 ; i < F ; i++)
70         {
71             for(int j = head[i] ; j != -1 ; j = p[j].next)
72             {
73                 if(low[i] != low[p[j].v])
74                     degree[low[i]] ++ ;
75                 
76             }
77         }
78         for(int i = 1 ; i <= F ; i ++)//  时间戳是从1开始的,所以low的值是可以到达F的,
79             if(degree[i] == 1)
80             ans ++ ;
81         printf("%d
",(ans + 1)/2) ;
82     }
83     return 0 ;
84 }
View Code
原文地址:https://www.cnblogs.com/luyingfeng/p/3925353.html