• 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)
    ",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
    ",bg_cnt - ans);
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    2015-04-10一些知识点
    2015-04-07一些知识点
    斐波那契数列算法
    进制转换算法
    Java中transient有何作用?
    RandomAccessFile的使用
    Java各种类型占用的字节数
    LineNumberReader类的使用
    PreparedStatement和Statement的区别
    ResultSet几种类型的区别
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3241718.html
Copyright © 2020-2023  润新知