双联通模板

点双联通模板——

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

 

边双联通分量(明日更新  

已填坑:

  

 1 int dfn[N],low[N],bccno[N],idx,stk[N],top,bcc_cnt;
 2 
 3 inline void tarjan(int x,int fa){
 4     dfn[x]=low[x]=++idx;
 5     stk[++top]=x;
 6     for(edges *i=head[x];i;i=i->last)    if(i->v!=fa){
 7         if(!dfn[i->v]){
 8             tarjan(i->v,x);
 9             low[x]=min(low[x],low[i->v]);
10         }else
11             low[x]=min(low[x],dfn[i->v]);
12     }
13     if(dfn[fa]<low[x]){
14         bcc_cnt++;int t;
15         do{
16             t=stk[top--];
17             bccno[t]=bcc_cnt;
18         }while(t!=x);
19     }
20 }

 

posted @ 2017-10-18 20:52  Troywar  阅读(182)  评论(0编辑  收藏  举报