Codeforces 1385E 拓扑排序(判环)
拓扑玩少了想不到
题意
给了n个点,m个边,其中有些边是有向边,有些是无向边。要求你给无向边规定方向,使得该图无换环。如果不能则输出-1。否则输出这m个边的顶点u,v,要求u指向v。
思路
用拓扑排序判断环。如果出现的点的次数不等于n,则是无解。
学大佬个小技巧:给每个点定义一个nub记录出现的前后顺序,最后输出无向边指向的时候,一定是nub小的指向nub大的(即先出现的指向后出现的)
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <string> #include <map> #include <iomanip> #include <algorithm> #include <queue> #include <stack> #include <set> #include <vector> // #include <bits/stdc++.h> #define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define sp ' ' #define endl '\n' #define inf 0x3f3f3f3f; #define FOR(i,a,b) for( int i = a;i <= b;++i) #define bug cout<<"--------------"<<endl #define P pair<int, int> #define fi first #define se second #define pb(x) push_back(x) #define ppb() pop_back() #define mp(a,b) make_pair(a,b) #define ms(v,x) memset(v,x,sizeof(v)) #define rep(i,a,b) for(int i=a;i<=b;i++) #define repd(i,a,b) for(int i=a;i>=b;i--) #define sca3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c)) #define sca2(a,b) scanf("%d %d",&(a),&(b)) #define sca(a) scanf("%d",&(a)); #define sca3ll(a,b,c) scanf("%lld %lld %lld",&(a),&(b),&(c)) #define sca2ll(a,b) scanf("%lld %lld",&(a),&(b)) #define scall(a) scanf("%lld",&(a)); using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a, ll b, ll mod){ll sum = 1;while (b) {if (b & 1) {sum = (sum * a) % mod;b--;}b /= 2;a = a * a % mod;}return sum;} const double Pi = acos(-1.0); const double epsilon = Pi/180.0; const int maxn = 3e5+10; int n,m; int de[maxn],nub[maxn]; vector<int>e[maxn]; queue<pair<int,int> >ans; int flag = 0; void Init() { cin>>n>>m; rep(i,1,n) { de[i] = 0; nub[i] = 0; e[i].clear(); } rep(i,1,m){ int u,v,x; cin>>x>>u>>v; if(x == 1){ e[u].pb(v); de[v]++; } ans.push(mp(u,v)); } } void Topsort() { flag = 1; queue<int>que; rep(i,1,n){ if(!de[i]){ que.push(i); } } int cnt = 0; while(que.size()){ int x = que.front();que.pop(); nub[x] = ++cnt; for(int i: e[x]){ de[i]--; if(de[i] == 0){ que.push(i); } } } if(cnt!=n) //是no flag=0; } int main() { //freopen("input.txt", "r", stdin); int _; scanf("%d",&_); while(_--) { Init(); Topsort(); if(flag==0){ cout<<"NO"<<endl; while(ans.size()) ans.pop(); continue; } cout<<"YES"<<endl; while(ans.size()){ int u = ans.front().fi; int v = ans.front().se; ans.pop(); if(nub[u] > nub[v]) swap(u,v); cout<<u<<sp<<v<<endl; } } }