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;
}