HDU 4612 Warm Up

给这题跪了。先是各种暴栈,然后又是各种WA,看来还是对题目的理解有点问题。

题意:给出一张无向图,然后让你在图中加一条边,使得图中剩下的桥最少。

思路:求边双连通分量,缩点后形成一棵树。然后求树的最长的两条链(这两条链不能交叉,应该说同根吧)。

鄙人跪就跪在重边这里了。如果节点1-2之间有一条重边,则1和2属于同一边双连通分量。。

  1 #pragma comment(linker, "/STACK:10240000000,10240000000")
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <vector>
  6 #include <stack>
  7 #include <algorithm>
  8 #define maxn 200010
  9 using namespace std;
 10 vector<int> G[maxn],g[maxn];
 11 int bcc_cnt,dfs_clock,bg_cnt;
 12 pair<int,int> bg[maxn];
 13 int pre[maxn],bccno[maxn],f[maxn],dp[maxn][2];
 14 stack<int> S;
 15 int dfs(int u,int fa){
 16     int lowu = pre[u] = ++dfs_clock;
 17     S.push(u);
 18     int cnt = 0;
 19     for(int i = 0;i < G[u].size();i++){
 20         int v = G[u][i];
 21         if(!pre[v]){
 22             int lowv = dfs(v,u);
 23             lowu = min(lowu,lowv);
 24             if(lowv > pre[u]){
 25                 bg[bg_cnt++] = make_pair(u,v);
 26             }
 27         }
 28         /*else if(pre[v] < pre[u] && v != fa){
 29             lowu = min(lowu,pre[v]);
 30         }*/
 31         else if(v == fa){
 32             if(cnt) lowu = min(lowu,pre[v]);
 33             cnt++;
 34         }
 35         else    lowu = min(lowu,pre[v]);
 36     }
 37     if(lowu == pre[u]){
 38         bcc_cnt++;
 39         while(1){
 40             int x = S.top();S.pop();
 41             bccno[x] = bcc_cnt;
 42             if(x == u)  break;
 43         }
 44     }
 45     return lowu;
 46 }
 47 
 48 void find_bcc(int n){
 49     memset(pre,0,sizeof(pre));
 50     dfs_clock = bg_cnt = bcc_cnt = 0;
 51     dfs(1,-1);
 52 }
 53 
 54 void dfs1(int u,int fa){
 55     dp[u][0] = dp[u][1] = f[u] = 0;
 56     for(int i = 0;i < g[u].size();i++){
 57         int v = g[u][i];
 58         if(v == fa) continue;
 59         dfs1(v,u);
 60         if(dp[v][0] + 1 <= dp[u][1])    continue;
 61         dp[u][1] = dp[v][0] + 1;
 62         if(dp[u][0] < dp[u][1]){
 63             swap(dp[u][0],dp[u][1]);
 64             f[u] = v;
 65         }
 66     }
 67 }
 68 
 69 void dfs2(int u,int fa,int now,int &ans){
 70     ans = max(ans,dp[u][0] + max(dp[u][1],now));
 71     //printf("dfs2(%d,%d,%d,%d)\n",u,fa,now,ans);
 72     for(int i = 0;i < g[u].size();i++){
 73         int v = g[u][i];
 74         if(v == fa) continue;
 75         if(f[u] == v)   dfs2(v,u,max(dp[u][1],now)+1,ans);
 76         else            dfs2(v,u,max(dp[u][0],now)+1,ans);
 77     }
 78 }
 79 
 80 int main()
 81 {
 82     int n,m;
 83     while(scanf("%d%d",&n,&m),n+m){
 84         for(int i = 1;i <= n;i++)   G[i].clear();
 85         for(int i = 0;i < m;i++){
 86             int a,b;
 87             scanf("%d%d",&a,&b);
 88             G[a].push_back(b);
 89             G[b].push_back(a);
 90         }
 91         find_bcc(n);
 92         for(int i = 1;i <= n;i++) g[i].clear();
 93         for(int i = 0;i < bg_cnt;i++){
 94             int a,b,x,y;
 95             x = bg[i].first;
 96             y = bg[i].second;
 97             a = bccno[x];
 98             b = bccno[y];
 99             g[a].push_back(b);
100             g[b].push_back(a);
101         }
102         int ans = 0;
103         dfs1(1,-1);
104         dfs2(1,-1,0,ans);
105         printf("%d\n",bg_cnt - ans);
106     }
107     return 0;
108 }
View Code

 

posted @ 2013-08-06 19:38  浙西贫农  阅读(168)  评论(0编辑  收藏  举报