点双连通模版 求割点,点双缩点

来源:互联网 发布:up to date数据库介绍 编辑:程序博客网 时间:2024/04/30 08:11

 一个割点属于他所临的所有双连通分量:(即点双连通)


#include<iostream>#include<string>#include<algorithm>#include<cstdlib>#include<cstdio>#include<set>#include<map>#include<vector>#include<cstring>#include<stack>#include<cmath>#include<queue>using namespace std;#define M 200004#define N 10004//黑匣子调用//1、init()//2、加边//3、find_bcc(1,n);若点标从1开始//4、得到每个点所属的连通分支Belong[] 是否为割点iscut[], 新图G[N]; 新图点标从1-blockstruct Edge{int from,to,nex;}edge[M*2];int head[N],edgenum;void add(int u, int v){Edge E ={u,v,head[u]}; edge[edgenum] = E ; head[u]=edgenum++;Edge E2={v,u,head[v]}; edge[edgenum] = E2; head[v]=edgenum++;}int DFN[N],dfs_clock,block;int Belong[N];bool iscut[N];// 割顶的bccno无意义stack<Edge> S;vector<int>G[N];int Tarjan(int u,int fa){int lowu, child=0;lowu = DFN[u] = ++dfs_clock;for(int i=head[u]; ~i; i = edge[i].nex){int v = edge[i].to;Edge e;e.from=u,e.to=v;if(!DFN[v]){S.push(e);child++;int lowv=Tarjan(v,u);lowu=min(lowu,lowv);if(lowv>=DFN[u]){iscut[u]=1;block++;G[block].clear();while(1){Edge x=S.top();S.pop();if(Belong[x.from]!=block){G[block].push_back(x.from);Belong[x.from]=block;}if(Belong[x.to]!=block){G[block].push_back(x.to);Belong[x.to]=block;}if(x.from==u&&x.to==v)break;}}}else if(DFN[v]<DFN[u]&&v!=fa){S.push(e);lowu=min(lowu,DFN[v]);}}if(fa<0&&child==1)iscut[u]=0;return lowu;}void find_bcc(int l, int r){memset(DFN,0,sizeof(DFN));memset(iscut,0,sizeof(iscut));memset(Belong,0,sizeof(Belong));dfs_clock=block=0;for(int i=l;i<=r;i++) if(!DFN[i])Tarjan(i,-1);}void init(){ memset(head, -1, sizeof head); edgenum = 0;}


0 0
原创粉丝点击