双联通模板
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; }
边双联通分量(明日更新
以上是关于双联通模板的主要内容,如果未能解决你的问题,请参考以下文章