## [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();
}
}