无向图边双+缩点

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;

struct my{
   int next;
   int v;
};

const int maxn=10000;
int adj[maxn],low[maxn],dfsn[maxn],dfn,fa,id[maxn],sadj[maxn],sfa;
my bian[maxn*2],sbian[maxn*2];
bool cut[maxn];

int sccnum;
int s[maxn],top,root;
vector<int>scc[maxn];

void myinsert(int u,int v){
     bian[++fa].v=v;
     bian[fa].next=adj[u];
     adj[u]=fa;
}

void smyinsert(int u,int v){
     sbian[++sfa].v=v;
     sbian[sfa].next=sadj[u];
     sadj[u]=sfa;
}


void tarjan(int x){
     s[++top]=x;
     low[x]=dfsn[x]=++dfn;
     int ch=0;
     if(x==root&&!adj[x]){
        scc[++sccnum].push_back(x);
        return ;
     }
     for (int i=adj[x];i;i=bian[i].next){
          int v=bian[i].v;
          if(!dfsn[v]){
            tarjan(v);
            low[x]=min(low[x],low[v]);
            if(dfsn[x]<=low[v]){
                ch++;
                sccnum++;
                int z;
                do{
                   z=s[top--];
                   scc[sccnum].push_back(z);
                }while(z!=v);
                scc[sccnum].push_back(x);
                if(x!=root||ch>1) cut[x]=true;
            }
          }else low[x]=min(low[x],dfsn[v]);
     }
}

int main(){
    int n,m;
    int u,v;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++){
        scanf("%d%d",&u,&v);
        myinsert(u,v);
        myinsert(v,u);
    }
    for (int i=1;i<=n;i++){
        if(!dfsn[i]) {
                root=i;
                tarjan(i);
        }
    }
   int num=sccnum;
   for (int i=1;i<=n;i++) if(cut[i]) id[i]=++num;
   for (int i=1;i<=sccnum;i++){
        for (int j=0;j<scc[i].size();j++){
            int x=scc[i][j];
            if(cut[x]){
                smyinsert(i,id[x]);
                smyinsert(id[x],i);
            }
        }
    }
    for (int i=1;i<=num;i++){
            printf("%d ",i);
        for (int j=sadj[i];j;j=sbian[j].next){
            int v=sbian[j].v;
            printf("%d ",v);
        }
        printf("
");
    }
return 0;
}
原文地址:https://www.cnblogs.com/lmjer/p/8696604.html