codeforces-1385E(拓撲排序)
阿新 • • 發佈:2020-07-20
Directing Edges
題目描述:
給定n個點m條邊,其中一些邊是有向的,一些邊是無向的,現在你需要將這些無向的邊確定方向,並判斷是否可以生成一個有向無環圖
思路:
顯而易見如果給出的有向邊沒有形成環的話,剩下的無向邊一定可以使他們不形成環,於是只需要將給定的有向邊做一遍拓撲排序,判斷是否已經成環,未成環的話就將所有無向邊按拓撲序定向即可使圖無環
程式碼:
#include<bits/stdc++.h> using namespace std; using ll = long long; const ll N = 1e6; const double PI = acos(-1.0); #define Test ll tesnum;tesnum = read();while(tesnum--) ll read(); vector<int> g[200005]; vector<pair<int,int>> v; int deg[N],pos[N]; int cnt; int main() { Test{ cnt = 0; v.clear(); int n,m; cin>>n>>m; for(int i = 1; i <= n; i++)g[i].clear(); for(int i = 1; i <= n; i++)deg[i] = pos[i] = 0; for(int i = 1; i <= m; i++){ int w,x,y; cin>>w>>x>>y; v.emplace_back(make_pair(x,y)); if(w==1){ g[x].emplace_back(y); deg[y]++; } } queue<int> q; for(int i = 1; i <= n; i++){ if(deg[i]==0) q.push(i); } while(!q.empty()) { int u = q.front(); q.pop(); pos[u] = ++cnt; for(int i = 0; i < g[u].size(); i++){ deg[g[u][i]]--; if(deg[g[u][i]]==0){ q.push(g[u][i]); } } } if(cnt==n){ cout<<"YES"<<endl; for(auto x:v){ if(pos[x.first]>pos[x.second]){ cout<<x.second<<" "<<x.first<<endl; }else cout<<x.first<<" "<<x.second<<endl; } }else{ cout<<"NO"<<endl; } }; return "BT7274", NULL; } inline ll read() { ll hcy = 0, dia = 1;char boluo = getchar(); while (!isdigit(boluo)) {if (boluo == '-')dia = -1;boluo = getchar();} while (isdigit(boluo)) {hcy = hcy * 10 + boluo - '0';boluo = getchar();} return hcy * dia; }