1. 程式人生 > >無向圖縮點poj3177 Redundant Paths

無向圖縮點poj3177 Redundant Paths

namespace while paths AI poj AC 新的 所有 mes

http://poj.org/problem?id=3177

題意:有n個牧場,互相連通,現在要求使得任意兩個牧場之間至少有兩條道路可走,求至少需要修多少條新的路

----------------------------------------

求出雙連通分量中,度為1的個數ans,答案即為(ans+1)/2
----------------------------------------

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5
#include <stack> 6 using namespace std; 7 const int N = 1e5 + 50; 8 int vis[N], low[N], dfn[N], cnt[N], belong[N]; 9 bool mp[5050][5050]; 10 int E, deep, n, m, cnt2; 11 stack<int>stk; 12 void dfs(int u, int fa) 13 { 14 vis[u] = 1; //在棧中 15 stk.push(u); 16 low[u] = dfn[u] = ++deep;
17 for (int i = 1; i <= n; i++) 18 { 19 if (mp[u][i] && i != fa) 20 { 21 if (!vis[i]){ 22 dfs(i, u); 23 low[u] = min(low[u], low[i]); 24 } 25 else 26 low[u] = min(low[u], dfn[i]); 27
} 28 } 29 if (low[u] == dfn[u] && vis[u]){ 30 cnt2++; //雙連通分量個數 31 while (stk.top() != u){ 32 vis[stk.top()] = 0; 33 belong[stk.top()] = cnt2; 34 stk.pop(); 35 } 36 vis[u] = 0; 37 belong[u] = cnt2; 38 stk.pop(); 39 } 40 } 41 int main(){ 42 while (scanf("%d%d", &n, &m) != EOF) 43 { 44 E = deep = 0; 45 memset(low, 0, sizeof(low)); 46 memset(dfn, 0, sizeof(dfn)); 47 memset(vis, 0, sizeof(vis)); 48 memset(cnt, 0, sizeof(cnt)); 49 memset(belong, 0, sizeof(belong)); 50 while (stk.size())stk.pop(); 51 cnt2 = 0; 52 for (int i = 1; i <= m; i++) 53 { 54 int u, v; 55 scanf("%d%d", &u, &v); 56 mp[u][v] = mp[v][u] = 1; 57 } 58 dfs(1, 1); 59 for (int i = 1; i <= n; i++) 60 for (int j = 1; j <= n; j++) 61 if (mp[i][j] && belong[i] != belong[j]) //遍歷所有邊,度++ 62 cnt[belong[i]]++, cnt[belong[j]]++, mp[i][j] = mp[j][i] = 0; 63 int ans = 0; 64 for (int i = 1; i <= cnt2; i++) 65 if (cnt[i] == 1) ans++; 66 cout << (ans + 1) / 2 << endl; 67 } 68 }

無向圖縮點poj3177 Redundant Paths