zoukankan      html  css  js  c++  java
  • 无向图点双+缩点

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    struct my{
        int next;
        int v;
    };
    
    const int maxn=10000;
    int low[maxn],dfsn[maxn],adj[maxn],fa,sfa,dfn;
    int bs[maxn],cnt;
    bool bridge[maxn*2];
    int sadj[maxn];
    my sbian[maxn*2];
    my bian[maxn*2];
    
    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,int dage){
         dfsn[x]=low[x]=++dfn;
         for (int i=adj[x];i;i=bian[i].next){
            int v=bian[i].v;
            if(!dfsn[v]){
                tarjan(v,i);
                low[x]=min(low[x],low[v]);
                if(dfsn[x]<low[v]){
                    bridge[i]=bridge[i^1]=1;
                }
            }
            else if(i!=(dage^1)){
                low[x]=min(low[x],dfsn[v]);
            }
         }
    }
    
    void dfs(int x){
         bs[x]=cnt;
         for (int i=adj[x];i;i=bian[i].next){
            int v=bian[i].v;
            if(bs[v]||bridge[i]) continue;
            dfs(v);
         }
    }
    
    int main(){
        int n,m;
        int u,v;
        fa=1;
        sfa=1;
        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]) tarjan(i,0);
        for (int i=1;i<=n;i++){
            if(!bs[i]){
                cnt++;
                dfs(i);
            }
        }
        //for (int i=2;i<fa;i+=2) if(bridge[i]) printf("%d %d
    ",bian[i].v,bian[i^1].v);
        for (int i=2;i<=fa;i++){
                int x=bian[i].v,y=bian[i^1].v;
            if(bs[x]==bs[y]) continue;
                    smyinsert(bs[x],bs[y]);//不需连两条边,算法自己会连成双向边
        }
        for (int i=1;i<=cnt;i++){
                printf("%d ",i);
            for (int j=sadj[i];j;j=sbian[j].next){
                 printf("%d ",sbian[j].v);
            }
            printf("
    ");
        }
    
    return 0;
    }
  • 相关阅读:
    Java高并发(1)
    Java基础知识之常见关键字(1)
    jQuery中attr()与prop()区别介绍
    win7下delphi中的help文档问题
    Delphi TMemo 可以显示、编辑多行文本
    TcxGrid
    Delphi学习手记——单引号和双引号的区别
    sql 系统表协助集合
    VCL安装有哪几种方法?
    sqlserver2008 服务器实例连接
  • 原文地址:https://www.cnblogs.com/lmjer/p/8687817.html
Copyright © 2011-2022 走看看