[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;
}
原文地址:https://www.cnblogs.com/AEMShana/p/13553380.html