• [DFS树] Codeforces 118E Bertown roads


    题目大意

    给定一个 (n) 个点 (m) 条边的无向连通图,给每条边定向,使得生成的有向图是强连通图,若不可能,输出0。(2leq nleq 10^5,n-1leq mleq 3 imes 10^5)

    题解

    如果原图有桥,显然给每条边定向后不可能强连通。考虑原图的DFS树,不妨令所有树边组成一棵外向树,这样从根节点出发可以到达图中的所有顶点。然后令所有非树边为后向边,那么任意结点都可以回到根节点,因为对于任意非根节点 (u),因为图中没有桥,一定存在一条非树边跨越连接 (u) 和它父亲的这条边,我们可以通过这条非树边到达 (u) 的祖先,如此重复操作就能到达根节点。因此,这样给边定向后得到的有向图是强连通图。

    Code

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <vector>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType &T){
        elemType X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        T=(w?-X:X);
    }
    
    struct Graph{
        struct edge{int Next,to,w;};
        edge G[600010];
        int head[100010];
        int cnt;
    
        Graph():cnt(2){}
        void clear(int node_num=0){
            cnt=2;
            if(node_num==0) memset(head,0,sizeof(head));
            else fill(head,head+node_num+5,0);
        }
        void add_edge(int u,int v,int w){
            G[cnt].w=w;
            G[cnt].to=v;
            G[cnt].Next=head[u];
            head[u]=cnt++;
        }
    };
    struct Edge{int u,v;};
    Edge E[300010];
    Graph G;
    int DFN[100010],dp[100010];
    bool vis[100010];
    int N,M,Index=0;
    bool flag;
    
    void DFS(int u,int fa,int id){
        vis[u]=true;DFN[u]=++Index;dp[u]=0;
        for(int i=G.head[u];i;i=G.G[i].Next){
            int v=G.G[i].to;
            int x=G.G[i].w;
            if(!vis[v]){DFS(v,u,G.G[i].w);dp[u]+=dp[v];E[x].u=u;E[x].v=v;}
            else if(v!=fa || (v==fa && id!=G.G[i].w)){
                if(DFN[v]<DFN[u]){++dp[u];E[x].u=u;E[x].v=v;}
                else{--dp[u];E[x].u=v;E[x].v=u;}
            }
        }
        if(dp[u]==0 && fa!=0) flag=true;
        return;
    }
    
    int main(){
        Read(N);Read(M);
        for(RG i=1;i<=M;++i){
            int u,v;
            Read(u);Read(v);
            G.add_edge(u,v,i);
            G.add_edge(v,u,i);
            E[i].u=u;E[i].v=v;
        }
        DFS(1,0,0);
        if(flag){printf("0
    ");return 0;}
        for(RG i=1;i<=M;++i)
            printf("%d %d
    ",E[i].u,E[i].v);
        return 0;
    }
    
  • 相关阅读:
    Red hat 5挂载U盘
    Win7+VMware Workstation环境下的CentOS-Linux网络连接设置
    rand()随机数的产生
    phpmyadmin数据库导入出错
    dede忽略错误
    wamp
    网页地图map
    Redefining already defined constructor
    SCREAM:Error suppression ignored for
    Python+selenium之疑难点解决之去除readonly的限制
  • 原文地址:https://www.cnblogs.com/AEMShana/p/13553380.html
Copyright © 2020-2023  润新知