[Topic link]
http://poj.org/problem?id=3694
Algorithm
First, we use the Tarjan algorithm to find all the side of the dual-link components, and then, the image of the contraction point
If the added edge (x, y) is in the same double-unicom component, the answer is the same, otherwise, the edges on the path to Belong[x]-belong[y] are marked, and the process can be accelerated by using the set
Code
#include <algorithm>#include<bitset>#include<cctype>#include<cerrno>#include<clocale>#include<cmath>#include<complex>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<deque>#include<exception>#include<fstream>#include<functional>#include<limits>#include<list>#include<map>#include<iomanip>#include<ios>#include<iosfwd>#include<iostream>#include<istream>#include<ostream>#include<queue>#include<Set>#include<sstream>#include<stdexcept>#include<streambuf>#include<string>#include<utility>#include<vector>#include<cwchar>#include<cwctype>#include<stack>#include<limits.h>using namespacestd;#defineMAXN 100010#defineMAXM 200010#defineMaxlog 20structedge{intTO,NXT;} E[MAXM<<2],EC[MAXM <<2];intI,J,N,M,ANS,TOT,CTOT,CNT,U,V,TIMER,LCA,X,Y,Q,TC;intHEAD[MAXN],CHEAD[MAXN],LOW[MAXN],DFN[MAXN],BELONG[MAXN],FA[MAXN],DEPTH[MAXN];intAnc[maxn][maxlog];BOOLIS_BRIDGE[MAXM <<1],visited[maxn];inlinevoidAddedge (intUintv) {Tot++; E[tot]=(Edge) {V,head[u]}; Head[u]=tot;} InlinevoidAddcedge (intUintv) {Ctot++; Ec[ctot]=(Edge) {V,chead[u]}; Chead[u]=Ctot;} InlinevoidTarjan (intUintt) { inti,v; Dfn[u]= Low[u] = + +timer; Visited[u]=true; for(i = head[u]; i; i =e[i].nxt) {v=e[i].to; if(!Visited[v]) {Tarjan (v,i); if(Low[v] > Dfn[u]) is_bridge[i] = is_bridge[i ^1] =true; Low[u]=min (low[u],low[v]); } Else if(I! = (t ^1)) Low[u] =min (low[u],dfn[v]); }}inlinevoidDfsintu) { inti,v; Belong[u]=CNT; for(i = head[u]; i; i =e[i].nxt) {v=e[i].to; if(Belong[v] | | is_bridge[i])Continue; DFS (v); }}inlinevoidLca_init () {inti,j,u,v; Queue<int>Q; while(!q.empty ()) Q.pop (); Q.push (1); depth[1] =1; while(!Q.empty ()) {u=Q.front (); Q.pop (); for(i = chead[u]; i; i =ec[i].nxt) {v=ec[i].to; if(Depth[v])Continue; DEPTH[V]= Depth[u] +1; anc[v][0] =u; for(j =1; J < Maxlog; J + +) Anc[v][j]= Anc[anc[v][j-1]][j-1]; Q.push (v); }}}inlineintLcaintXinty) { inti,t; if(Depth[x] >Depth[y]) swap (x, y); T= Depth[y]-Depth[x]; for(i =0; i < Maxlog; i++) { if(T & (1<<i)) y=Anc[y][i]; } if(x = = y)returnx; for(i = Maxlog-1; I >=0; i--) { if(Anc[x][i]! =Anc[y][i]) {x=Anc[x][i]; Y=Anc[y][i]; } } returnanc[x][0];} InlineintGet_root (intx) { if(Fa[x] = = x)returnx; returnFA[X] =Get_root (fa[x]);}intMain () { while(SCANF ("%d%d", &n,&m) && (n | |m)) {tot=1; Ctot= CNT = Timer =0; for(i =1; I <= N; i++) {Head[i]=0; Chead[i]=0; Dfn[i]=0; Low[i]=0; Belong[i]=0; Visited[i]=false; Fa[i]=i; Depth[i]=0; } for(i =1; I <=2* m +1; i++) Is_bridge[i] =false; for(i =1; I <= m; i++) {scanf ("%d%d",&u,&v); Addedge (U,V); Addedge (V,u); } for(i =1; I <= N; i++) { if(!Dfn[i]) Tarjan (i,0); } for(i =1; I <= N; i++) { if(!Belong[i]) {CNT++; DFS (i); } } for(U =1; U <= N; u++) { for(j = head[u]; j; j =e[j].nxt) {v=e[j].to; if(Belong[u]! =Belong[v]) {Addcedge (belong[u],belong[v]); Addcedge (Belong[v],belong[u]); }}} ans= CNT-1; Lca_init (); printf ("Case %d:\n",++TC); scanf ("%d",&q); while(q--) {scanf ("%d%d",&u,&v); X= Belong[u]; y =Belong[v]; Lca=LCA (x, y); X=get_root (x); while(Depth[x] >Depth[lca]) {Fa[x]= anc[x][0]; Ans--; X=get_root (x); } y=get_root (y); while(Depth[y] >Depth[lca]) {Fa[y]= anc[y][0]; Ans--; Y=get_root (y); } printf ("%d\n", ans); } printf ("\ n"); } return 0; }
[POJ 3694] Network