AcWing3696 -- topsort & 贪心

1. 题目描述

给定我们一些有向边和无向边,判断在将所有无向边确定方向后,能否生成一个有向无环图



2. 思路

思路其实真的非常简单。
我根据题目给定的有向边做一次 \(topsort\),如果失败,说明无论剩下的无向边在怎么确定方向,都不可能无环。
如果成功,那么我们便成功确定了拓扑序。那么对于剩下的没有确定方向的边,我们按照拓扑序确定方向即可。此时,一定能构成有向无环图。
题目说了,给定的图不一定联通,事实上,不联通并不影响拓扑序,如果多个点之间不联通,那么他们的拓扑序是任意的。



3. 代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;
const int N = 200010, M = N, INF = 0x3f3f3f3f;

int T, n, m, k;
int h[N], e[M], ne[M], idx;
int d[N], q[N], pos[N];
PII edges[M];

bool topsort()
{
    int hh = 0, tt = -1;
    for(int i = 1; i <= n; i ++ )   
        if(!d[i])   q[ ++ tt ] = i;
    while(hh <= tt)
    {
        int t = q[hh ++ ];
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if( -- d[j] == 0)   q[ ++ tt ] = j;
        }
    }
    
    return tt == n - 1;
}

void add(int a, int b)
{
    d[b] ++ , e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

int main()
{
    cin >> T;
    while(T -- )
    {
        cin >> n >> m;
        // init
        idx = 0;
        k = 0;
        memset(h, -1, sizeof(int) * (n + 10));
        memset(d, 0, sizeof(int) * (n + 10));
        
        for(int i = 0; i < m; i ++ )
        {
            int op, a, b;
            cin >> op >> a >> b;
            if(op)  add(a, b);
            else edges[k ++ ] = {a, b}; // store undirected edge
        }
        
        if(!topsort())  puts("NO");
        else 
        {
            puts("YES");
            // first print directed edges
            for(int i = 1; i <= n; i ++ )
                for(int j = h[i]; j != -1; j = ne[j])
                    cout << i << ' ' << e[j] << endl;
            // get top sort
            for(int i = 0; i < n; i ++ )    pos[q[i]] = i;
            // set direct for undirected edge
            for(int i = 0; i < k; i ++ )
            {
                auto [a,b] = edges[i];
                if(pos[a] > pos[b]) cout << b << ' ' << a << endl;
                else    cout << a << ' ' << b << endl;
            }
        }
        
    }
    return 0;
}
posted @ 2023-03-27 13:02  光風霽月  阅读(16)  评论(0编辑  收藏  举报