poj3694(Network)
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; struct my{ int v; int next; }; const int maxn=200000+10; int adj[maxn],adj2[maxn],low[maxn],dfn[maxn],fa,fa2,c[maxn],dfsn,tot,d[maxn]; int f[maxn][20],fat[maxn*4]; bool inedge[maxn*4]; queue<int>Q; my bian[maxn*4],bian2[maxn*4]; void init(){ fa=1; fa2=1; dfsn=0; tot=0; memset(adj,0,sizeof(adj)); memset(adj2,0,sizeof(adj2)); memset(bian,0,sizeof(bian)); memset(bian2,0,sizeof(bian2)); memset(dfn,0,sizeof(dfn)); memset(f,0,sizeof(f)); memset(low,0,sizeof(low)); memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); memset(inedge,0,sizeof(inedge)); while(!Q.empty()) Q.pop(); } void myinsert(int u,int v){ bian[++fa].v=v; bian[fa].next=adj[u]; adj[u]=fa; } void myinsert2(int u,int v){ bian2[++fa2].v=v; bian2[fa2].next=adj2[u]; adj2[u]=fa2; } void tarjan(int x,int in_edge){ low[x]=dfn[x]=++dfsn; for (int i=adj[x];i;i=bian[i].next){ int v=bian[i].v; if(!dfn[v]){ tarjan(v,i); low[x]=min(low[x],low[v]); if(low[v]>dfn[x]){ inedge[i]=1; inedge[i^1]=1; } } else if((in_edge^1)!=i) low[x]=min(low[x],dfn[v]); } } void dfs(int x){ c[x]=tot; for (int i=adj[x];i;i=bian[i].next){ int v=bian[i].v; if(c[v]||inedge[i]) continue; dfs(v); } } void bfs(){ Q.push(1); d[1]=1; while(!Q.empty()){ int u=Q.front();Q.pop(); for (int i=adj2[u];i;i=bian2[i].next){ int v=bian2[i].v; if(d[v]) continue; d[v]=d[u]+1; f[v][0]=u; for (int j=1;j<=17;j++) f[v][j]=f[f[v][j-1]][j-1]; Q.push(v); } } } int lca(int x,int y){ if(d[x]>d[y]) swap(x,y); for (int i=17;i>=0;i--){ if(d[x]<=d[f[y][i]]) y=f[y][i]; } if(x==y) return x; for (int i=17;i>=0;i--){ if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; } return f[x][0]; } int getfa(int x){ if(x==fat[x]) return x; return fat[x]=getfa(fat[x]); } int main(){ //freopen("A.out","w",stdout); int n,m; int u,v; int T=0,t; while(scanf("%d%d",&n,&m)&&n){ init(); for (int i=1;i<=m;i++){ scanf("%d%d",&u,&v); myinsert(u,v); myinsert(v,u); } for (int i=1;i<=n;i++){ if(!dfn[i]) tarjan(i,0); } for (int i=1;i<=n;i++){ if(!c[i]){ tot++; dfs(i); } } for (int i=2;i<=fa;i++){ int x=bian[i].v; int y=bian[i^1].v; if(c[x]!=c[y]) myinsert2(c[x],c[y]); } bfs(); int ans=tot-1; T++; printf("Case %d:\n",T); scanf("%d",&t); for (int i=1;i<=tot;i++) fat[i]=i; while(t--){ int x,y; scanf("%d%d",&u,&v); if(c[u]==c[v]) ; else { x=c[u]; y=c[v]; int p=lca(x,y); x=getfa(x); while(d[p]<d[x]){ fat[x]=f[x][0]; ans--; x=getfa(x); } y=getfa(y); while(d[p]<d[y]){ fat[y]=f[y][0]; ans--; y=getfa(y); } } printf("%d\n",ans); } printf("\n"); } return 0; }