【Codeforces 1385 E】Directing Edges

题目链接

点我呀

翻译

给你一个 (n) 个节点 (m) 条边的图,但是有一些边的方向还没有确定。

问你能否将其中没有确定方向的边确定了,使得最后形成的整张图没有环。

题解

一说就会做的题。

先将已经确定了方向的边作为图的边,然后在这个有向图的基础上跑拓扑排序。

记录下每个节点在拓扑排序中的序号。

然后在最后输出答案的时候,对于没有确定方向的边,将其方向改为从拓扑排序序号小的节点指向序号大的节点。

这样,肯定是满足拓扑排序的要求的,即谁在谁前面先输出。

然后如果拓扑排序做不了的话 (已经确定方向的边生成的有向图的基础上做的) ,说明已经有环了。则无解。

否则按照上面的方案输出就好,一定有解。

代码

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

const int M = 2e5;

struct abc{
    int p,x,y;
};

int n, m;
abc a[M + 10];
vector<int> g[M + 10];
int du[M + 10], order[M + 10];
queue<int> dl;

int main(){
    #ifdef LOCAL_DEFINE
        freopen("E://9.AlgorithmCompetition//Visitor.txt","r",stdin);
    #endif
    ios::sync_with_stdio(0),cin.tie(0);
    int T;
    cin >> T;
    while (T--){
        cin >> n >> m;
        for (int i = 1;i <= n; i++){
            g[i].clear();
            du[i] = 0;
        }
        for (int i = 1;i <= m; i++){
            int p,x,y;
            cin >> p >> x >> y;
            if (p == 1){
                g[x].push_back(y);
                du[y]++;
            }
            a[i].p = p;
            a[i].x = x;
            a[i].y = y;
        }
        for (int i = 1;i <= n; i++)
            if (du[i] == 0){
                dl.push(i);
            }
        int cur = 0;
        while (!dl.empty()){
            int x = dl.front();dl.pop();
            order[x] = ++cur;
            for (int i = 0;i < (int)g[x].size(); i++){
                int y = g[x][i];
                du[y]--;
                if (du[y] == 0){
                    dl.push(y);
                }
            }
        }
        if (cur!=n){
            cout << "NO" << endl;
        }else{
            cout << "YES" << endl;
            for (int i = 1;i <= m; i++){
                if (a[i].p == 0 && order[a[i].x] > order[a[i].y]){
                    swap(a[i].x,a[i].y);
                }
                cout << a[i].x <<" "<<a[i].y << endl;
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/13349742.html