E. Directing Edges——(拓扑排序)
程序员文章站
2024-03-13 23:35:04
...
题意
根据图给的边,构造一个有向无环图(标准的拓扑排序)。
总结
比赛中,自己在考虑出度,不知道自己在什么。出度为0干嘛:我挺服自己的
入度为0:代表这个点不在有向无环图,然后不断的拆边,入度减减,构造,存在环的话,肯定边数构造会少。
用set存在好处
1:可以删边
2:知道u,可以判断是否存在u-v这条边。(本题作用:判断有向边 or 无向边)
题目链接
//#pragma GCC optimize(2)
//#pragma GCC target ("sse4")
#include<bits/stdc++.h>
//typedef long long ll;
#define ull unsigned long long
#define int long long
#define F first
#define S second
#define endl "\n"//<<flush
#define eps 1e-6
#define base 131
#define lowbit(x) (x&(-x))
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define MAXN 0x7fffffff
#define INF 0x3f3f3f3f3f3f3f3f
#define ferma(a,b) pow(a,b-2)
#define mod(x) (x%mod+mod)%mod
#define pb push_back
#define decimal(x) cout << fixed << setprecision(x);
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
template<typename T> inline T fetch(){T ret;cin >> ret;return ret;}
template<typename T> inline vector<T> fetch_vec(int sz){vector<T> ret(sz);for(auto& it: ret)cin >> it;return ret;}
template<typename T> inline void makeUnique(vector<T>& v){sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());}
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
// freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int N = 2e5 + 5;
vector<set<int> > G(N);
int in[N];
signed main()
{
IOS;
file();
int t;
cin>>t;
while(t--)
{
int n, m;
cin>>n>>m;
for(int i = 1; i <= n; i++)
G[i].clear(),in[i] = 0;
set<int>se;
while(m--)
{
int tag,x,y;
cin>>tag>>x>>y;
se.insert(x);
se.insert(y);
G[x].insert(y);
if(tag)
in[y]++;
else
G[y].insert(x);
}
queue<int>que;
for(int i=1;i<=n;i++)
if(in[i]==0)
que.push(i),se.erase(i);
vector<pair<int,int> > ans;
while(!que.empty())
{
int u = que.front();
que.pop();
vector<int>vec;
for(auto v:G[u])
{
if(!G[v].count(u))
in[v]--;
if(!in[v]&&se.count(v))
que.push(v),se.erase(v);
ans.pb({u,v});
vec.pb(v);
}
for(auto v:vec)
G[u].erase(v),G[v].erase(u);
}
if(se.empty())
{
cout<<"YES"<<endl;
for(auto it:ans)
cout<<it.F<<" "<<it.S<<endl;
}
else
cout<<"NO"<<endl;
}
return 0;
}