给这题跪了。先是各种暴栈,然后又是各种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 }