Links: http://poj.org/problem?id=3694
Test instructions: Given a connected graph, add one edge at a time to find the number of bridges remaining.
Ideas:
Given an undirected connected graph, add a u->v Edge to the effect of this edge on the number of bridges remaining in the graph :
If the u,v is in the same strong unicom component, is no effect added. Otherwise , all the bridges from u,v 's LCA to the u,v side are no longer bridges.
in u,v belong to different strong connected components, DFN ( set to v) merge up until DFN[V] < Dfn[u] u Span style= "font-family: the song Body;" > merge up until u = v 1 .
Merging uses and checks to optimize the path during the merge process, or time out.
#include <iostream>#include<cstdio>#include<string>#include<cstring>#include<cstdlib>#include<queue>#include<vector>#include<algorithm>Const intINF =0x3f3f3f3f;using namespaceStd;typedefLong LongLL;Const intn=100008, m=400008;intHead[n],tot,n,m,dfn[n],deep;intBridge;intFa[n], cnt[n], pre[n];structnode{intTo,next;} E[M];voidinit () {memset (head,-1,sizeof(head)); Tot=0; Bridge=0; for(inti =1; I <= N; i++) {Fa[i]=i; Cnt[i]=1; }}intFind (intx) { while(X! =Fa[x]) {x=Fa[x]; } returnx;}BOOLUnion (intXinty) { intFX =Find (x); intFY =Find (y); if(fx!=FY) { if(cnt[fx]>Cnt[fy]) {Fa[fy]=FX; CNT[FX]+=Cnt[fy]; }Else{FA[FX]=fy; CNT[FY]+=CNT[FX]; } return true; }Else{ return false; }}inlinevoidAddintUintTo ) {e[tot].to=to ; E[tot].next=Head[u]; Head[u]=tot++;}intDfsintUintFA) { intLowu = Dfn[u] = ++deep;//Lowu is the farthest ancestor that u and its descendants can reach. for(intI=head[u];~i;i=E[i].next) { intv =e[i].to; if(!dfn[v]) {//leaf Edge, u to V and v not accessedPRE[V] =u; intLOWV =Dfs (v, u); Lowu=min (Lowu, LOWV); if(Lowv >Dfn[u]) {Bridge++; }Else{Union (U, v); } }Else if(Dfn[v] < Dfn[u] && v! =FA) {Lowu= Min (Lowu, dfn[v]);//Back to Edge } } returnLowu;}voidTarjan () {memset (DFN,0,sizeof(DFN)); deep=0; for(intI=1; i<=n;i++){ if(!Dfn[i]) {Pre[i]=i; DFS (i,-1); } }}intLCA (intUintv) { if(Find (u) = =Find (v)) { returnBridge; } if(Dfn[u] >Dfn[v]) {Swap (U, v); } while(Dfn[u] <Dfn[v]) { if(Union (V, Pre[v])) {Bridge--; } v=Pre[v]; } while(U! =v) { if(Union (U, Pre[u])) {Bridge--; } u=Pre[u]; } returnBridge;}intMain () {intt =0; while(~SCANF ("%d%d", &n, &m) && (n | |m)) {init (); intA, B, q; while(m--) {scanf ("%d%d", &a, &b); Add (A, b); Add (b, a); } Tarjan (); scanf ("%d", &q); printf ("Case %d:\n",++t); while(q--) {scanf ("%d%d", &a, &b); printf ("%d\n", LCA (A, b)); } printf ("\ n"); } return 0;}
POJ3694 Network (Tarjan dual-link LCA bridge)