题目链接:https://codeforces.com/contest/1385/problem/E
题目大意:
给出n个点,m条边的图,有些边是固定方向的,有些边则没有固定方向,问能否改变一些没有固定方向的边的方向吗,使得整张图中没有环
输出 边的方向情况
题目思路:
首先,将不能改变方向的边 按照拓扑排序 ,跑一遍,如果出现图,把么是一定不可以的,因为此时不可以改变边的方向
否则,一定可以
只需要将能改变方向的边,将其按照拓扑序 由小指到大 一定不会出现环的情况
Code:
/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(3)
#include <bits/stdc++.h>
ll n,m,p;
int t[maxn],x[maxn],y[maxn];
vector<int>v[maxn];
int in[maxn];
int id[maxn];
void work(){
queue<int>q;
for(int i=1;i<=n;i++){
if(!in[i]) q.push(i);
}
int cot = 0;
while(!q.empty()){
int u = q.front();q.pop();
id[u] = ++cot;
for(int e:v[u]){
in[e]--;
if(!in[e]) q.push(e);
}
}
if(cot<n) printf("NO\n");
else{
printf("YES\n");
for(int i=1;i<=m;i++){
if(t[i]) printf("%d %d\n",x[i],y[i]);
else if(id[x[i]] < id[y[i]]) printf("%d %d\n",x[i],y[i]);
else if(id[x[i]] > id[y[i]])printf("%d %d\n",y[i],x[i]);
}
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
read(n);read(m);
for(int i=1;i<=n;i++) in[i] = 0,v[i].clear();
for(int i=1;i<=m;i++){
scanf("%d%d%d",&t[i],&x[i],&y[i]);
if(t[i]){
v[x[i]].push_back(y[i]);
in[y[i]] ++;
}
}
work();
}
return 0;
}
/***
3 3 = 9
3 2 = 6
3 1 = 3
***/