当前位置: 代码迷 >> 综合 >> Codeforces1385 E. Directing Edges(拓扑排序)
  详细解决方案

Codeforces1385 E. Directing Edges(拓扑排序)

热度:73   发布时间:2024-01-30 03:21:16.0

题意:

给定n个点m条边的图,其中有的边是有向边,有的边是无向边。
现在要求你将每条无向边修改为有向边,问如何修改能使得图中不存在环。
判断是否有解,如果有解则输出一组解

数据范围:n<=2e5

解法:

对有向图拓扑排序并记录时间戳dfn。
对于每条无向边,令dfn小的点直线dfn大的点即可(比较显然,这样不会出现环)。

注意如果原图的有向图已经出现环那么无解

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e5+5;
vector<pair<int,int> >temp;
vector<int>g[maxm];
int dfn[maxm];
int d[maxm];
int n,m;
signed main(){int T;cin>>T;while(T--){cin>>n>>m;//initfor(int i=1;i<=n;i++){g[i].clear();d[i]=0;}temp.clear();//for(int i=1;i<=m;i++){int op,a,b;cin>>op>>a>>b;if(!op){//无向temp.push_back({a,b});}else{//有向g[a].push_back(b);d[b]++;}}//拓扑排序int idx=0;//dfnqueue<int>q;for(int i=1;i<=n;i++){if(!d[i]){q.push(i);}}while(!q.empty()){int x=q.front();q.pop();dfn[x]=++idx;for(int v:g[x]){if(d[v]){d[v]--;if(!d[v]){q.push(v);}}}}//if(idx!=n){//不是所有点都入队,那么说明出现环了puts("NO");continue;}else{puts("Yes");for(auto i:temp){int a=i.first,b=i.second;if(dfn[a]>dfn[b]){swap(a,b);}cout<<a<<' '<<b<<endl;}for(int x=1;x<=n;x++){for(int v:g[x]){cout<<x<<' '<<v<<endl;}}}}return 0;
}