AcWing364 网络(无向图缩点)

边双的经典例题,动态加边只需要在加边的两点网上求父节点到lca,将其中的的桥去掉后路径压缩

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int isce[N],h[N],ne[N],e[N],idx;
int dfn[N],low[N],fa[N],depth[N];
int times,n,m,ans;
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void init(){
    memset(h,-1,sizeof h);
    memset(dfn,0,sizeof dfn);
    memset(low,0,sizeof low);
    memset(fa,0,sizeof fa);
    memset(depth,0,sizeof depth);
    memset(isce,0,sizeof isce);
    ans=0,times=0;
}
void tarjan(int u){
    dfn[u]=low[u]=++times;
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(!dfn[j]){
            fa[j]=u,depth[j]=depth[u]+1;
            tarjan(j);
            low[u]=min(low[u],low[j]);
            if(dfn[u]<low[j]){
                ++ans;
                isce[j]=1;
            }
        }
        else if(j!=fa[u]) low[u]=min(low[u],dfn[j]);
    }
}
int num[N];
void lca(int a,int b){
    if(depth[a]<depth[b])
        swap(a,b);
    int top=0;
    while(depth[a]>depth[b]){
        num[++top]=a;
        if(isce[a]){
            ans--;
            isce[a]=0;
        }
        a=fa[a];
    }
    while(a!=b){
        num[++top]=a;
        num[++top]=b;
        if(isce[a]){
            ans--;
            isce[a]=0;
        }
        if(isce[b]){
            ans--;
            isce[b]=0;
        }
        a=fa[a];
        b=fa[b];
    }
    for(int i=1;i<=top;i++){
        fa[num[i]]=a;
    }
}
int main(){
    ios::sync_with_stdio(false);
    int sign=1;
    while(cin>>n>>m){
        if(n==0&&m==0)
            break;
        int i;
        init();
        cout<<"Case "<<sign++<<":"<<endl;
        for(i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            add(a,b);
            add(b,a);
        }
        for(i=1;i<=n;i++){
            if(!dfn[i]){
                fa[i]=i;
                tarjan(i);
            }
        }
        int q;
        cin>>q;
        while(q--){
            int a,b;
            cin>>a>>b;
            lca(a,b);
            cout<<ans<<endl;
        }
        cout<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-05-26 20:27  朝暮不思  阅读(173)  评论(0编辑  收藏  举报