##连通性##

来源:互联网 发布:魔兽世界mac版本 编辑:程序博客网 时间:2024/06/05 17:35


//强联通struct edge{    int to,next,num;  //增设num为判重边}e[M];int scc,hea,tim;int low[N],dfs[N],tr[N],sccno[N];int head[N],o;//记得初始化void add(int x,int y,int m){    e[o].to=y;    e[o].next=head[x];    e[o].num=m;    head[x]=o++;}scanf("%d%d",&x,&y);{add(x,y,i); add(y,x,i);}void tarjandfs(int now,int from){   int v;    tr[++hea]=now; in[now]=1;    dfs[now]=++tim; low[now]=dfs[now];    for (int k=head[now];k!=-1;k=e[k].next)        {   v=e[k].to;            if (e[k].num==from) continue; //imp!            if (dfs[v]==0)//生成树的边                {tarjandfs(v,e[k].num);  low[now]=min(low[now],low[v]);                }            else if (in[v])//回边            low[now]=min(low[now],dfs[v]);        }    /*具体剥离出每个强连通分量,一般用于一般有向图*/    if(low[now]==dfs[now])          { int i;            scc++;            do{i=tr[hea--];  sccno[i]=scc; in[i]=0;}while(i!=now);          }}//因为有向图除了树枝边、回边还有交叉边,所以in数组不可少。而无向图没有交叉边(除了树枝边就是回边),故可以直接else而省去in数组。主函数:tcc=tim=hea=0;memset(dfs,0,sizeof(dfs));memset(low,0,sizeof(low));memset(in,0,sizeof(in));//初始化tarjandfs(1,-1);//前提:题目保证是个连通图(弱连通)//否则要for (i=1;i<=n;i++) if (!dfs[i]) tarjandfs(i,-1);1.求割边if (dfs[now]<low[v]&&e[k].num==1) an[ans++]=e[k].id;2.去掉关节点u,将连通图分成几个连通分量?(1).u是关节点,几个儿子几个分量(2)不是根节点,d个子女w,满足low[w]>=dfn[u],为d+1个分量具体实现:for (i=1;i<=max;i++) ans[i]=1; ans[1]=0;//ans[i]=1代表i上头的那一部分(有根的那部分)//&&在low[now]=min(low[now],low[v]);这句话后面加if (dfs[u]<=low[w]) ans[u]++;



//双联通//代码1int dfs[N],low[N],bccno[N];//3个数组均memset为0int n,m;int tim,bcc;struct edge{    int u,v;    edge(int x=0,int y=0):u(x),v(y){}}e[M];vector<int > BCC[N],g[N];bool iscut[N];//初始化为0stack<edge> S;int tarjandfs(int u,int from=-1){   int lowu=dfs[u]=++tim;    int child=0;    for (int i=0;i<g[u].size();i++)        {   int v=g[u][i];            edge e=edge(u,v);            if (!dfs[v])                {                    S.push(e);                    child++;                    int lowv=tarjandfs(v,u);                    lowu=min(lowu,lowv);                    if (lowv>=dfs[u])                        {   iscut[u]=1;                            bcc++; BCC[bcc].clear();                            while (1)                                {                                    edge x=S.top(); S.pop();                                    if (bccno[x.u]!=bcc) {BCC[bcc].pb(x.u);bccno[x.u]=bcc;}                                    if (bccno[x.v]!=bcc) {BCC[bcc].pb(x.v);bccno[x.v]=bcc;}                                    if (x.u==u&&x.v==v) break;                                }                        }                }            else if (dfs[v]<dfs[u]&&v!=from){                S.push(e);                lowu=min(lowu,dfs[v]);            }        }    if (from<0&&child==1) iscut[u]=0;    return lowu;}//bcc=tim=0;//memset(iscut,0,sizeof(iscut));//memset(dfs,0,sizeof(dfs));//memset(low,0,sizeof(low));//memset(bccno,0,sizeof(bccno));//for (int i=1;i<=n;i++)if (!dfs[i]) tarjandfs(i,-1);//S保证第一组数据前是empty的

//双联通//代码2int dfs[N],low[N],bccno[N];//3个数组均memset为0int tr[N];int n,m;int tim,bcc,hea;vector<int > BCC[N],g[N];bool iscut[N],vv[N];//2个初始化为0void tarjandfs(int u,int from=-1){   low[u]=dfs[u]=++tim;    tr[++hea]=u; vv[u]=1;    int child=0;    for (int i=0;i<g[u].size();i++)        {   int v=g[u][i];            if (v==from) continue;            if (!dfs[v])                {   tarjandfs(v,u);child++;                    low[u]=min(low[u],low[v]);                    if (dfs[u]<=low[v])                        {   iscut[u]=1;                            int x;                            bcc++;BCC[bcc].clear();                            do{x=tr[hea--];  bccno[x]=bcc; BCC[bcc].pb(x); vv[x]=0; }while(x!=v);                            BCC[bcc].pb(u);                       }                }            else if (vv[v])                low[u]=min(low[u],dfs[v]);        }    if (from<0&&child==1) iscut[u]=0;}//bcc=tim=hea=0;//memset(dfs,0,sizeof(dfs));//memset(low,0,sizeof(low));//memset(bccno,0,sizeof(bccno));//memset(vv,0,sizeof(vv));//memset(iscut,0,sizeof(iscut));//for (int i=1;i<=n;i++)if (!dfs[i]) tarjandfs(i,-1);

0 0
原创粉丝点击