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;
}

 

posted @ 2018-07-29 21:36  lmjer  阅读(98)  评论(0编辑  收藏  举报