双联通模板

Posted Troy Ricardo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双联通模板相关的知识,希望对你有一定的参考价值。

点双联通模板——

hdu 3749

#define Troy 10/18/2017

#include <bits/stdc++.h>

using namespace std;

inline int read(void){
    int s=0,k=1;char ch=getchar();
    while(ch<0|ch>9)    ch==-?k=-1:0,ch=getchar();
    while(ch>47&ch<=9)    s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=2e4+5;

int n,m,q;
vector<int> bel[N],bcc[N];

struct edges{
    int v;edges *last;
}edge[N<<1],*head[N>>1];int cnt;

inline void push(int u,int v){
    edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
}

int dfn[N],low[N],dfx,stk_u[N],stk_v[N],top,T,size[N],K[N],root,scc,bccno[N];

inline void unionn(int x,int y){
    bcc[y].push_back(x);
    bel[x].push_back(y);
    bccno[x]=y;
}

inline void Tarjan(int x,int fa){
    dfn[x]=low[x]=++dfx;
    K[x]=T;
    for(edges *i=head[x];i;i=i->last)   if(i->v!=fa){
        if(!dfn[i->v]){        
            stk_u[++top]=x; stk_v[top]=i->v;
            Tarjan(i->v,x);
            low[x]=min(low[x],low[i->v]);
            if(low[i->v]>=dfn[x]){
                scc++;
                bcc[scc].clear();
                int u,v;
                while(1){ u=stk_u[top],v=stk_v[top--];
                    if(bccno[u]!=scc)   unionn(u,scc);
                    if(bccno[v]!=scc)   unionn(v,scc);
                    if(u==x&&v==i->v) break;
                }
            }
        }else   if(dfn[i->v]<dfn[x]){            
            stk_u[++top]=x; stk_v[top]=i->v;
            low[x]=min(low[x],dfn[i->v]);
        }
    }
}

inline void init(){
    cnt=0;memset(head,0,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(bccno,0,sizeof(bccno));
    for(int i=0;i<=n;i++)
        bel[i].clear();
    for(int i=1,u,v;i<=m;i++){
        u=read(),v=read();
        push(u,v);push(v,u);
    }
}

inline void Judge(int a,int b){
    for(int i=0;i<bel[a].size();i++)    
        for(int j=0;j<bel[b].size();j++)
            if(bel[a][i]==bel[b][j]&&bcc[bel[a][i]].size()>2){
                puts("two or more");
                return ;
            }
    puts("one");
}

inline void work(){
    dfx=0;scc=0;
    for(int i=0;i<n;i++)
        if(!dfn[i]){
            T++;root=i;
            Tarjan(i,-1);
        }
    while(q--){
        int a=read(),b=read();
        if(K[a]!=K[b])puts("zero");
        else            Judge(a,b);
    }
}

int main(){
    int t=0;
    while(1){
        n=read(),m=read(),q=read();
        if(n==0&&m==0&&q==0)    break;
        t++;
        printf("Case %d:\n",t);
        init();
        work();
    }
    return 0;
}

 

边双联通分量(明日更新

以上是关于双联通模板的主要内容,如果未能解决你的问题,请参考以下文章

边双联通分量(构造边双联通图)

边双联通分量与割边

POJ 1515 双联通分量

双联通分量复习

poj-3177(并查集+双联通分量+Tarjan算法)

双联通分量与二分图