http://poj.org/problem?id=3694
用tarjan算出桥,用lca算出公共祖先 把路上的边更新掉 原来的桥变为不是桥 看一解题报告感觉有一部分是不用加的 不知道是不是数据水 没加交上也A了。。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 using namespace std; 7 #define N 1000010 8 #define M 2000010 9 struct node 10 { 11 int u,v,next; 12 }edge[M*2]; 13 int head[N],t,dfn[N],iscut[N],fa[N],low[N],num,dc; 14 void init() 15 { 16 t = 0; 17 memset(head,-1,sizeof(head)); 18 memset(dfn,0,sizeof(dfn)); 19 memset(low,0,sizeof(low)); 20 fa[1] = 0; 21 num=0; 22 dc=0; 23 } 24 void add(int u,int v) 25 { 26 edge[t].u = u; 27 edge[t].v = v; 28 edge[t].next = head[u]; 29 head[u] = t++; 30 edge[t].u = v; 31 edge[t].v = u; 32 edge[t].next = head[v]; 33 head[v] = t++; 34 } 35 void tarjan(int u,int faa) 36 { 37 int i,flag=1; 38 dfn[u] = low[u] = ++dc; 39 for(i = head[u] ; i != -1 ; i = edge[i].next) 40 { 41 int v = edge[i].v; 42 if(flag&&faa==v) 43 { 44 flag = 0; 45 continue; 46 } 47 if(!dfn[v]) 48 { 49 fa[v] = u; 50 tarjan(v,u); 51 low[u] = min(low[v],low[u]); 52 if(low[v]>dfn[u]) 53 { 54 num++; 55 iscut[v] = 1; 56 } 57 } 58 else 59 low[u] = min(dfn[v],low[u]); 60 } 61 } 62 void lca(int u,int v) 63 { 64 int t; 65 if(dfn[u]<dfn[v]) 66 {t = u;u = v;v = t;} 67 while(dfn[u]>dfn[v]) 68 { 69 if(iscut[u]) 70 { 71 iscut[u] = 0; 72 num--; 73 } 74 u = fa[u]; 75 } 76 while(u!=v) 77 { 78 if(iscut[v]) 79 { 80 iscut[v] = 0; 81 num--; 82 } 83 /*if(iscut[u]) 84 { 85 iscut[u] = 0; 86 num--; 87 }*/ 88 v = fa[v];u = fa[u]; 89 } 90 } 91 int main() 92 { 93 int n,m,q,a,b,kk=0; 94 while(cin>>n>>m) 95 { 96 kk++; 97 if(n==0&&m==0) 98 break; 99 init(); 100 while(m--) 101 { 102 cin>>a>>b; 103 add(a,b); 104 } 105 tarjan(1,0); 106 printf("Case %d:\n",kk); 107 cin>>q; 108 while(q--) 109 { 110 cin>>a>>b; 111 lca(a,b); 112 cout<<num<<endl; 113 } 114 puts(""); 115 } 116 return 0; 117 }