P2017 [USACO09DEC]晕牛Dizzy Cows
给你一张有向无向混合图,要求你为无向边定向,使得图上没有环。
开始看到被卡了,考虑tarjan但是又有无向边又有有向边的确不是很好做
考虑全部是有向图但是没有环的DAG图,一般我们的判定方式都是用拓扑排序
但是如果你把边全部搞进来,发现没法排,怎么办呢?
思路在于你看到其实无向边是转化成有向边的,所以说其实进行拓扑排序的时候其实无向边是无关紧要的
那么我们只先读进来有向边,进行拓扑排序,就会得到一个序列
我们知道如果一个点在另一个点顺序的后面的话,如果我们添加这个点回去的边显然是不合理的,所以我们每读入一条无向边的时候我们判断这个点在拓扑排序里面位置的大小,如果a>b就代表a到b可能有路线,但是b绝对不能返回a,那么此时如果有一条ab要你选择,建立a到b不会使b回到a,判断条件也就非常明显了
所以简述就是:
读入,对于有向边
拓扑
读入无向边
按上面的进行判定输出答案
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #define N 1000006 5 using namespace std; 6 struct node{ 7 int u,v; 8 }e[N]; 9 int first[N],nxt[N],cnt,c[N];int n,p1,p2,ru[N],ans[N],tot; 10 void add(int u,int v){ 11 e[++cnt].u=u; 12 e[cnt].v=v; 13 nxt[cnt]=first[u]; 14 first[u]=cnt; 15 } 16 void topsort(){ 17 priority_queue<int>q; 18 for(int i=1;i<=n;i++)if(!ru[i])q.push(i),ans[++tot]=i; 19 while(!q.empty()){ 20 int u=q.top(); 21 q.pop(); 22 for(int i=first[u];i;i=nxt[i]){ 23 int v=e[i].v; 24 ru[v]--; 25 if(!ru[v]){ 26 ans[++tot]=v; 27 q.push(v); 28 } 29 } 30 } 31 } 32 int main(){ 33 ios::sync_with_stdio(false); 34 cin>>n>>p1>>p2; 35 for(int i=1;i<=p1;i++){ 36 int a,b; 37 cin>>a>>b; 38 add(a,b); 39 ru[b]++; 40 } 41 topsort(); 42 for(int i=1;i<=n;i++)c[ans[i]]=i; 43 for(int i=1;i<=p2;i++){ 44 int a,b; 45 cin>>a>>b; 46 if(c[a]>c[b]){ 47 cout<<b<<" "<<a<<endl; 48 } 49 else cout<<a<<" "<<b<<endl; 50 } 51 return 0; 52 }
over