Codeforces Round #656 (Div. 3) E. Directing Edges
阿新 • • 發佈:2020-07-18
給定一張圖,圖中給出一些有向邊,一些無向邊。
要求給所有無向邊賦予方向後能夠使整張圖無環。
已知給定的圖中無自環,無重邊
解題思路:
若給定的有向邊已經成環,那麼必然輸出NO,否則都可以構造出解。
考慮原圖的拓撲排序,根據兩點的進隊時間,對於某一無向邊,只要使邊上兩點進隊時間也滿足拓撲序,就可以使得圖依舊無環。
#pragma warning(disable:4996) #include<iostream> #include<algorithm> #include<bitset> #include<tuple> #include<unordered_map> #include<fstream> #include<iomanip> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<list> #include<queue> #include<stack> #include<sstream> #include<cstdio> #include<ctime> #include<cstdlib> #define INF 0x3f3f3f3f #define inf 0x7FFFFFFF #define MOD 998244353 #define moD 1000000003 #define pii pair<ll,int> #define eps 1e-8 #define equals(a,b) (fabs(a-b)<eps) #define bug puts("bug") #define re register #define fi first #define se second #define pb push_back const int maxn = 1e6 + 5; const double Inf = 10000.0; const double PI = acos(-1.0); typedef long long ll; typedef unsigned long long ull; using namespace std; vector<int> vec[maxn]; int InDeg[maxn]; queue<int> q; int num; int n; int t[maxn]; bool topsort() { while (!q.empty()) q.pop(); num = 0; for (int i = 1; i <= n; i++) if (!InDeg[i]) q.push(i); int tt = 0; while (!q.empty()) { int now = q.front(); q.pop(); num++; t[now] = tt++; for (int i = 0; i < vec[now].size(); i++) { if (--InDeg[vec[now][i]] == 0) q.push(vec[now][i]); //入度為零,進入佇列 } } return n == num; } void solve() { int tmp, x, y; memset(InDeg, 0, sizeof InDeg); memset(vec, 0, sizeof vec); memset(t, 0, sizeof t); int m; scanf("%d%d", &n, &m); vector<pii> ans; vector<pii> res; for (int i = 0; i < m; i++) { scanf("%d%d%d", &tmp, &x, &y); if (tmp == 1) vec[x].push_back(y), InDeg[y]++, res.emplace_back(x, y); else ans.emplace_back(x, y); } if (!topsort()) { puts("NO"); return; } for (int i = 0; i < ans.size(); i++) { if (t[ans[i].first] > t[ans[i].se]) res.emplace_back(ans[i].se, ans[i].fi); else if (t[ans[i].first] <= t[ans[i].se])res.emplace_back(ans[i].fi, ans[i].se); } puts("YES"); for (int i = 0; i < res.size(); i++) printf("%d %d\n", res[i].fi, res[i].se); } int main() { int T; scanf("%d", &T); while (T--) solve(); }