poj 3694 Network(割边+lca)
题目链接:http://poj.org/problem?id=3694
题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目。
分析:通常的做法是:先求出该无向图的桥的数目count和边双连通分量,缩点,每次加边(u,v),判断若u,v属于同一个双连通分量,则桥的数目不变,否则,桥的数目必定会减少,这时桥减少的数目明显和最近公共祖先lca有关,用裸的lca就行了,每次u和v向父节点回退,如果该节点是桥的端点,则count--,直到u==v为止。
有个优化:其实不用缩点,只要在求出桥的时候标记一下,然后在用lca求减少桥的数目时,利用dfn[]就行了,因为u,v的最近公共祖先dfn[]一定相等。
AC代码如下:
1 #include<cstdio> 2 #include<cstring> 3 const int N=1000000+5; 4 const int M=2000000+5; 5 struct EDGE{ 6 int v,next; 7 }edge[M]; 8 int first[N],dfn[N],low[N],bri[N],pre[N]; 9 int g,cnt,count; 10 void AddEdge(int u,int v) 11 { 12 edge[g].v=v; 13 edge[g].next=first[u]; 14 first[u]=g++; 15 } 16 int min(int a,int b) 17 { 18 return a<b?a:b; 19 } 20 void Tarjan(int u,int fa) 21 { 22 int i,v; 23 low[u]=dfn[u]=++cnt; 24 for(i=first[u];i!=-1;i=edge[i].next) 25 { 26 v=edge[i].v; 27 if(i==(fa^1)) 28 continue; 29 if(!dfn[v]) 30 { 31 pre[v]=u; 32 Tarjan(v,i); 33 low[u]=min(low[u],low[v]); 34 if(low[v]>dfn[u]) 35 { 36 count++; 37 bri[v]=1; 38 } 39 } 40 else 41 low[u]=min(low[u],dfn[v]); 42 } 43 } 44 void lca(int u,int v) 45 { 46 while(dfn[u]>dfn[v]) 47 { 48 if(bri[u]) 49 { 50 count--; 51 bri[u]=0; 52 } 53 u=pre[u]; 54 } 55 while(dfn[v]>dfn[u]) 56 { 57 if(bri[v]) 58 { 59 count--; 60 bri[v]=0; 61 } 62 v=pre[v]; 63 } 64 while(u!=v) 65 { 66 if(bri[u]) 67 { 68 count--; 69 bri[u]=0; 70 } 71 if(bri[v]) 72 { 73 count--; 74 bri[v]=0; 75 } 76 u=pre[u]; 77 v=pre[v]; 78 } 79 } 80 int main() 81 { 82 int n,m,i,u,v,q; 83 int cas=1; 84 while(scanf("%d%d",&n,&m)!=EOF) 85 { 86 if(n==0&&m==0) 87 break; 88 g=cnt=count=0; 89 memset(first,-1,sizeof(first)); 90 memset(dfn,0,sizeof(dfn)); 91 memset(bri,0,sizeof(bri)); 92 for(i=0;i<m;i++) 93 { 94 scanf("%d%d",&u,&v); 95 AddEdge(u,v); 96 AddEdge(v,u); 97 } 98 for(i=1;i<=n;i++) 99 if(!dfn[i]) 100 Tarjan(i,-1); 101 scanf("%d",&q); 102 printf("Case %d:\n",cas++); 103 for(i=0;i<q;i++) 104 { 105 scanf("%d%d",&u,&v); 106 lca(u,v); 107 printf("%d\n",count); 108 } 109 printf("\n"); 110 } 111 return 0; 112 }
posted on 2013-10-22 11:24 jumpingfrog0 阅读(552) 评论(0) 编辑 收藏 举报