[CF1385E] Directing Edges

## [CF1385E] Directing Edges - 拓扑排序

### Description

给定一个由有向边与无向边组成的图,现在需要你把所有的无向边变成有向边,使得形成的图中没有环,如果可以做到请输出该图,否则直接输出 NO

### Solution

只添加有向边,进行拓扑排序,令所有无向边也从拓扑序小的节点指向拓扑序大的节点,就一定不会成环

``` cpp
#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1000005;
vector<int> g[N];

int ind, topo[N];

void dfs(int p)
{
    if (topo[p])
        return;
    topo[p] = -1;
    for (int q : g[p])
        dfs(q);
    topo[p] = --ind;
}

void solve()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        g[i].clear(), topo[i] = 0;
    ind = n;
    vector<pair<int, int>> und;
    for (int i = 1; i <= m; i++)
    {
        int t, x, y;
        cin >> t >> x >> y;
        if (t)
            g[x].push_back(y);
        else
            und.push_back({x, y});
    }
    for (int i = 1; i <= n; i++)
        if (topo[i] == 0)
            dfs(i);
    for (int i = 1; i <= n; i++)
        for (int j : g[i])
            if (topo[i] > topo[j])
            {
                cout << "NO" << endl;
                return;
            }
    cout << "YES" << endl;
    for (auto [x, y] : und)
    {
        if (topo[x] <= topo[y])
            cout << x << " " << y << endl;
        else
            cout << y << " " << x << endl;
    }
    for (int i = 1; i <= n; i++)
        for (int j : g[i])
            cout << i << " " << j << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
原文地址:https://www.cnblogs.com/mollnn/p/14384058.html