poj 3694 Network

来源:互联网 发布:excel圆环图数据标志 编辑:程序博客网 时间:2024/05/18 03:03

分析:先缩点成树,然后模拟LCA过程。

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn = 200500;//const int maxm = 405000;struct Node{    int v,next;}e[maxn*4],tree[maxn*4];int bridge,vis[maxn],pre[maxn],head[maxn];int dfn[maxn],low[maxn],head1[maxn],id[maxn],index,top,num,scc,sta[maxn];void add(int a,int b){    e[num].v=b;    e[num].next=head[a];    head[a]=num++;}void add_tree(int a,int b){    tree[num].v=b;    tree[num].next=head1[a];    head1[a]=num++;}void init(){    top=0;    scc=num=index=0;    memset(dfn,0,sizeof(dfn));}void tarjan(int u,int fa){    dfn[u]=low[u]=++index;    sta[++top]=u;    int cnt=0;    for(int i=head[u];i!=-1;i=e[i].next){        int v=e[i].v;        if(!dfn[v]){            tarjan(v,u);            low[u]=min(low[u],low[v]);        }        else if(fa==v){            if(cnt) low[u]=min(low[u],dfn[v]);            cnt++;        }        else{            low[u]=min(low[u],dfn[v]);        }    }    if(dfn[u]==low[u]){        int x;        scc++;        do{            x=sta[top--];            id[x]=scc;           // printf("%d ",x);        }while(x!=u);      //  printf("\n");    }}int ran[maxn];void lca_dfs(int u,int dept,int fa){    ran[u]=dept;    for(int i=head1[u];i!=-1;i=tree[i].next){        int v=tree[i].v;        if(v==fa) continue;        low[v]=1;        lca_dfs(v,dept+1,u);        pre[v]=u;    }}void lca(int u,int v){    while(ran[u]>ran[v]){        if(low[u]){            low[u]=0;            bridge--;        }        u=pre[u];    }    while(ran[u]<ran[v]){        if(low[v]){            low[v]=0;            bridge--;        }        v=pre[v];    }    while(u!=v){        if(low[u]){            bridge--;            low[u]=0;        }        if(low[v]){            bridge--;            low[v]=0;        }        u=pre[u];        v=pre[v];    }}int main(){    int n,m,con=1;    while(~scanf("%d %d",&n,&m) && (n+m)){        init();        for(int i=0;i<=n;i++){            head[i]=-1;            vis[i]=0;        }        for(int i=0;i<m;i++){            int a,b;            scanf("%d %d",&a,&b);            add(a,b);            add(b,a);        }        for(int i=1;i<=n;i++){            if(!dfn[i]){                tarjan(i,-1);            }        }        num=0;        for(int i=0;i<=n;i++){            head1[i]=-1;            low[i]=0;        }        for(int u=1;u<=n;u++){           // vis[u]=1;            for(int i=head[u];i!=-1;i=e[i].next){                int v=e[i].v;              //  if(vis[v]) continue;                if(id[u]!=id[v]){                    add_tree(id[u],id[v]);                   // printf("link----%d %d\n",id[u],id[v]);                }            }        }        lca_dfs(1,1,-1);        bridge=scc-1;//        for(int i=1;i<=scc;i++){//            printf("%d---%d\n",i,ran[i]);//        }        int q;        scanf("%d",&q);        printf("Case %d:\n",con++);        while(q--){            int a,b;            scanf("%d %d",&a,&b);            if(id[a]!=id[b]){                lca(id[a],id[b]);            }           // else{                printf("%d\n",bridge);           // }        }       // printf("%d\n",bridge);//        for(int i=1;i<=n;i++){//            printf("%d---%d\n",i,id[i]);//        }    }}


原创粉丝点击