HDU 3394 双连通分量 桥 Railway

第一个答案是统计图中桥的个数

如果一个点-双连通分量中边的个数大于点的个数那么这个块中所有的边都是冲突的,累加到第二个答案中去。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <map>
  7 #include <stack>
  8 #define MP make_pair
  9 #define Ft first
 10 #define Sd second
 11 using namespace std;
 12 
 13 typedef pair<int, int> PII;
 14 
 15 const int maxn = 10000 + 10;
 16 
 17 int n, m;
 18 
 19 vector<int> G[maxn];
 20 
 21 vector<PII> bcc[maxn];
 22 stack<PII> S;
 23 int pre[maxn], low[maxn], dfs_clock, bcc_cnt;
 24 
 25 int ans1, ans2;
 26 
 27 void dfs(int u, int fa)
 28 {
 29     low[u] = pre[u] = ++dfs_clock;
 30     for(int i = 0; i < G[u].size(); i++)
 31     {
 32         int v = G[u][i];
 33         if(!pre[v])
 34         {
 35             S.push(MP(u, v));
 36             dfs(v, u);
 37             low[u] = min(low[u], low[v]);
 38 
 39             if(low[v] >= pre[u])
 40             {
 41                 bcc_cnt++;
 42                 bcc[bcc_cnt].clear();
 43                 for(;;)
 44                 {
 45                     PII x = S.top(); S.pop();
 46                     bcc[bcc_cnt].push_back(x);
 47                     if(x.Ft == u && x.Sd == v) break;
 48                 }
 49                 if(low[v] > pre[u]) ans1++; //bridge
 50             }
 51         }
 52         else if(v != fa && pre[v] < pre[u])
 53         {
 54             S.push(MP(u, v));
 55             low[u] = min(low[u], pre[v]);
 56         }
 57     }
 58 }
 59 
 60 void find_bcc()
 61 {
 62     memset(pre, 0, sizeof(pre));
 63     dfs_clock = bcc_cnt = 0;
 64     for(int i = 0; i < n; i++) if(!pre[i]) dfs(i, -1);
 65 }
 66 
 67 bool vis[maxn];
 68 
 69 int main()
 70 {
 71     while(scanf("%d%d", &n, &m) == 2 && n)
 72     {
 73         for(int i = 0; i < n; i++) G[i].clear();
 74         while(m--)
 75         {
 76             int u, v; scanf("%d%d", &u, &v);
 77             G[u].push_back(v);
 78             G[v].push_back(u);
 79         }
 80 
 81         ans1 = ans2 = 0;
 82         find_bcc();
 83 
 84         for(int i = 1; i <= bcc_cnt; i++)
 85         {
 86             memset(vis, false, sizeof(vis));
 87             int vertex = 0, sz = bcc[i].size();
 88             for(int j = 0; j < sz; j++)
 89             {
 90                 PII x = bcc[i][j];
 91                 if(!vis[x.Ft]) { vis[x.Ft] = true; vertex++; }
 92                 if(!vis[x.Sd]) { vis[x.Sd] = true; vertex++; }
 93             }
 94             if(sz > vertex) ans2 += sz;
 95         }
 96 
 97         printf("%d %d\n", ans1, ans2);
 98     }
 99 
100     return 0;
101 }
代码君

 

posted @ 2015-08-12 10:47  AOQNRMGYXLMV  阅读(173)  评论(0编辑  收藏  举报