牛客练习赛 25 E题 定向 【桥 + 思维】 无向图定方向变强连通图

版权声明:本文为博主原创文章,喜欢就点个赞吧 https://blog.csdn.net/Anxdada/article/details/82026887

传送门
题意: 给定一个无向图, 然后你要给这幅图每条边加上一个方向, 使得这个图是有向图强连通

思路: 关键在于如何判断无解的情况, 如果能保证当前的图有解, 那么直接dfs一下就可以出答案. 仔细想想知道. 其实就是判断一下当前这幅图是否有”桥” , 联通分量的定义的桥, 如果有桥则一定无解, 否则就有解, 然后dfs一下就可以得到答案了. 细节请看代码
AC Code

const int maxn = 1e6+5;
int dfn[maxn], low[maxn];
int dfs_id, bri_num;
int n, m;
int cnt , head[maxn];
void init() {
    Fill(dfn, 0); Fill(low, 0);
    cnt = 2; Fill(head, -1);
    dfs_id = bri_num = 0;
}
struct node {
    int to, next;
}e[maxn<<1];
void add(int u, int v) {
    e[cnt] = node{v, head[u]};
    head[u] = cnt++;
}
void Findbri(int u, int fa) {
    dfn[u] = low[u] = ++dfs_id;
    for(int i = head[u] ; ~i ; i = e[i].next) {
        int v = e[i].to;
        if((i^1) == fa) continue;
        if(!dfn[v]) {
            Findbri(v, i);
            low[u] = min(low[u], low[v]);
            if(low[v] > dfn[u]) bri_num++;
        }
        else low[u] = min(low[u], dfn[v]);
    }
}
int ans[maxn], vis[maxn];
void dfs(int u, int fa) {
    vis[u] = 1;
    for(int i = head[u] ; ~i ; i = e[i].next) {
        int to = e[i].to;
        ans[i/2] = (i&1) ? 0 : 1;
        if (to == fa || vis[to]) continue;
        dfs(to, u);
    }
}
void solve() {
    scanf("%d%d", &n, &m);
    init();
    for (int i = 1 ; i <= m ; i ++) {
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v); add(v, u);
    }
    for (int i = 1 ; i <= n ; i ++) {
        if (!dfn[i]) Findbri(i, -1);
    }
    if (bri_num) {
        puts("impossible");
        return ;
    }
    for (int i = 1 ; i <= n ; i ++) {
        if (!vis[i]) dfs(i, -1);
    }
    for (int i = 1 ; i <= m ; i ++) {
        printf("%d", ans[i]);
    }
    printf("\n");
}

猜你喜欢

转载自blog.csdn.net/Anxdada/article/details/82026887