codeforces E. Directing Edges

codeforces E. Directing Edges_第1张图片

题目

题意:

给你很多条边,这其中有无向边和有向边,你现在要将全部无向边变成有向边,但是要保证不能出现环,如果没有满足条件的情况,那么输出NO,如果满足输出YES以及每一条边。

思路:

因为有向边的已经确定了,所以就可以直接存度,然后我们开始考虑无向边,假如此时的无向边的的其中一个度为 0 0 0,那么我们就将无向边的方向指向另一个顶点,那么此时的入度还是为 0 0 0,假如此时的入度都不为 0 0 0,那么此时无论取哪个都对于判定是否有环没有影响,如果因为其他边的原因,这个无向边有度为 0 0 0的时候,那么依旧指向另外一个,所以也就是说,无向边的指向对于有无环没有任何影响。
所以最后的时候,我们只要用拓扑排序判定有向边是否有环,还有用一个数组记录此时这个点的出现的顺序,因为无向边的顶点的指向是有规定的,如果拓扑排序的时候后出现的那个点,肯定就是被指的那个点,不然起始点的度就不会为 0 0 0了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef vector<int> veci;
typedef vector<ll> vecl;
typedef pair<int, int> pii;
template <class T>
inline void read(T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return ;
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1:1;
    ret = (c == '-') ? 0:(c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return ;
}
int xxxxxxxxx = 1;
inline void outi(int x) {if (x > 9) outi(x / 10);putchar(x % 10 + '0');}
inline void outl(ll x) {if (x > 9) outl(x / 10);putchar(x % 10 + '0');}
inline void debug(ll x) {cout << xxxxxxxxx++ << " " << x << endl;}
inline void debugs(string s) {cout << s << endl;}
const int maxn = 2e5 + 10;
int in[maxn], id[maxn];
vector<int> edge[maxn];
vector<pii > vec;
int main() {
    int t; read(t); while (t--) {
        vec.clear();
        for (int i = 0; i <= maxn; i++) edge[i].clear();
        memset(in, 0, sizeof(in));
        memset(id, 0, sizeof(id));
        int n, m; read(n), read(m); for (int i = 0; i < m; i++) {
            int opt, u, v; read(opt), read(u), read(v);
            if (opt == 1) in[v]++, edge[u].push_back(v);
            else vec.push_back(make_pair(u, v));
        }
        queue<int> q;
        for (int i = 1; i <= n; i++) if (in[i] == 0) q.push(i);
        int sz = 0;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            id[u] = sz++;
            for (int i = 0; i < edge[u].size(); i++) {
                int v = edge[u][i];
                in[v]--;
                if (in[v] == 0) q.push(v);
            }
        }
        if (sz != n) {
            printf("NO\n");
            continue;
        } else {
            printf("YES\n");
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j < edge[i].size(); j++) {
                    int v = edge[i][j];
                    printf("%d %d\n", i, v);
                }
            }
            for (int i = 0; i < vec.size(); i++) {
                int u = vec[i].first, v = vec[i].second;
                if (id[u] > id[v]) swap(u, v);
                printf("%d %d\n", u, v);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(codeforces)