POJ 3352 【边双连通分量】.cpp 加多少条边可以使无向图变成双连通分量
题意:
某个公园要修路..这将导致两个景点无法连通
输入:
给出n m 表示有n个景点 m条路
接下来m行每行有a b 表示a景点和b景点相连..
问加几条边可以使任意两个景点都相连..
思路:
先用tarjan算法求出每个连通分量
然后对无向图来说..变成双连通分量的方法就是(入度为1的点+1)/ 2
Tips:
无视POJ的simple输入输出 都是坑人的..T0T
还有就是现在这样tarjan算法第一次调用的时候就是tarjan(1, 1)
Code:
View Code
1 #include <stdio.h> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define clr(x) memset(x, 0, sizeof(x)) 6 const int INF = 0x1f1f1f1f; 7 const int MAXN = 1010; 8 9 struct Edge 10 { 11 int to; 12 int next; 13 }edge[1000010]; 14 int head[MAXN]; 15 int tot; 16 17 void add(int s, int u) 18 { 19 edge[tot].to = u; 20 edge[tot].next = head[s]; 21 head[s] = tot++; 22 23 edge[tot].to = s; 24 edge[tot].next = head[u]; 25 head[u] = tot++; 26 } 27 28 int low[MAXN], dfn[MAXN]; 29 int col[MAXN]; 30 int ti; 31 32 void tarjan(int u, int v) 33 { 34 int i, j, k; 35 low[v] = dfn[v] = ++ti; 36 for(i = head[v]; i != -1; i = edge[i].next) { 37 k = edge[i].to; 38 if(k == u) continue; 39 if(!dfn[k]) 40 tarjan(v, k); 41 low[v] = min(low[v], low[k]); 42 } 43 } 44 45 int n; 46 int deg[MAXN]; 47 int ans; 48 void solve() 49 { 50 int i, j, k; 51 clr(deg); 52 clr(dfn); 53 ans = 0, ti = 0; 54 tarjan(1, 1); 55 for(i = 1; i <= n; ++i) { 56 for(j = head[i]; j != -1; j = edge[j].next) { 57 k = edge[j].to; 58 if(low[i] != low[k]) deg[low[i]]++; 59 } 60 } 61 62 for(i = 1; i <= n; ++i) 63 if(deg[i] == 1) ans++; 64 65 ans = (ans+1)/2; 66 } 67 68 int main() 69 { 70 int i, j, k; 71 char sip[20]; 72 int m, a, b; 73 while(scanf("%d %d", &n, &m) != EOF) 74 { 75 tot = 0; 76 memset(head, 0xff, sizeof(head)); 77 78 while(m--) { 79 scanf("%d %d", &a, &b); 80 add(a, b); 81 } 82 83 solve(); 84 85 printf("%d\n", ans); 86 } 87 return 0; 88 }