链接:https://ac.nowcoder.com/acm/contest/1077/D
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld
题目描述
The cows have taken to racing each other around the farm but they get very dizzy when running in circles, and everyone knows that dizzy cows don’t produce any milk. Farmer John wants to convert all of the two-way cow paths in the farm to one-way paths in order to eliminate any ‘cycles’ and prevent the cows from getting dizzy. A ‘cycle’ enables a cow to traverse one or more cow paths and arrive back at her starting point, thus completing a loop or circle.
The farm comprises N pastures (1 <= N <= 100,000) conveniently numbered 1…N. M1 (1 <= M1 <= 100,000) one-way cow paths and M2 two-way cow paths (1 <= M2 <= 100,000) connect the pastures. No path directly connects a pasture to itself, although multiple paths might connect two different pastures. A cow may or may not be able to travel between any two given pastures by following a sequence of cow paths.
Your job is to assign a direction to the two-way cow paths such that the entire farm (ultimately with only one-way paths) has no cycles. That is, there should be no sequence of one-way cow paths which leads back to its starting position. The existing one-way cow paths do not form a cycle and should be left as they are.
One-way cow paths run from pasture Ai (1 <= Ai <= N) to pasture Bi (1 <= Bi <= N). Two-way cow paths connect pastures Xi (1 <= Xi <= N) and Yi (1 <= Yi <= N).
Consider this example:

             1-->2|  /|| / ||/  |3<--4

The cow paths between pastures 1 and 3, 2 and 3, and 2 and 4 are two-way paths. One-way paths connect 1 to 2 and also 4 to 3. One valid way to convert the two-way paths into one-way paths in such a way that there are no cycles would be to direct them from 1 to 3, from 2 to 3, and from 3 to 4:

         1-->2|  /|| / |vL  v3<--4

输入描述:

  • Line 1: Three space separated integers: N, M1, and M2
  • Lines 2…1+M1: Line i+1 describes a one-way cow path using two space separated integers: Ai and Bi
  • Lines 2+M1…1+M1+M2: Line i+M1+1 describes a two-way cow path using two space separated integers: Xi and Yi
    输出描述:
  • Lines 1…M2: Line i should contain two space-separated integers: either Xi and Yi or Yi and Xi, depending on the direction assigned to the i-th two-way path. The two-way paths must appear in the same order in the output as they do in the input. If there is no solution, output “-1” on a single line.
    示例1
    输入
    复制
4 2 3
1 2
4 3
1 3
4 2
3 2

输出
复制

1 3
4 2
2 3

/*
题意是:给无向边标定方向,使图不构成环。
不构成环,很容易想到拓扑排序

对应代码2:
一开始我是加入了所以边进行拓扑排序(不算无向边的度),
当队列中出来的这个点有无向边与它相连时,输出:当前点–>通过无向边与之相连的点,
但是我不知道如何 标记 那已经输出的那条无向边(即方向已经确定的边)已经确定方向了,
,不标记的化会再输出它的反向边。
(后来傻不拉几的才反映过来实质是一个反向边标记问题
快速找到该条边的反向边标号,并标记不可用)。
如何快速找到一条边的反向边?(每条边已经标号并且方向边标号相邻):

nowID ^1 为反向边的编号,

对应代码1:
不标记反向边的话,要换一种思路:
只需要对有向边上的点做拓扑排序,
记录每个点的出场顺序(拓扑序),
让拓扑序小的指向大的就ok。

*/
代码一:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
struct Edge
{int to;int val;int nxt;
} edge[N<<1];
int head[N],idx,top[N];
int in[N];
int n,m1,m2;
void add_edge(int from,int to,int val)
{edge[idx].to = to;edge[idx].val = val;edge[idx].nxt = head[from];head[from] = idx++;in[to]++;
}void topSort()
{queue<int>q;int tp = 0;for(int i = 1; i <= n ; i++){if(!in[i]){q.push(i);top[i] = ++tp;}}while(!q.empty()){int k = q.front();q.pop();for(int i = head[k]; ~i; i = edge[i].nxt){int t = edge[i].to;if(!(--in[t])){q.push(t);top[t] = ++tp;}}}
}
int main()
{cin>>n>>m1>>m2;int x,y;memset(head,-1,sizeof(head));for(int i = 0; i < m1; i++){cin>>x>>y;add_edge(x,y,1);}topSort();for(int i = 0; i < m2; i++){cin>>x>>y;if(top[x] < top[y])cout<<x<<" "<<y<<endl;elsecout<<y<<" "<<x<<endl;}return 0;
}

代码二:

//标记 无向边中已经确定方向的 反向边

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int n,m1,m2,idx;
struct Edge
{int from;int to;int val;int nxt;
} edge[N<<1];
int head[N],in[N];
//head[i]存i扩展出来的边中最大的那个编号(即最后一条扩展边的编号)
inline void add_edge(int from,int to,int val)
{edge[idx].from = from;edge[idx].to = to;edge[idx].val = val;edge[idx].nxt = head[from];head[from] = idx++;
}
void topSort()
{queue<int>q;for(int i = 1; i <= n; i++){if(!(in[i])) q.push(i);}while(!q.empty()){int k = q.front();q.pop();for(int i = head[k]; ~i; i = edge[i].nxt){if(edge[i].val == 1){int t = edge[i].to;if(!(--in[t])) q.push(t);}else if (edge[i].val == 2){//cout<<edge[i].from<<" "<<edge[i].to<<endl;edge[i^1].val = -1;}}}
}
int main()
{memset(head,-1,sizeof(head));cin>>n>>m1>>m2;int x,y;for(int i = 0; i < m1; i++){cin>>x>>y;add_edge(x,y,1);in[y]++;}/*边标号从0开始,如果前面已经标号边数为奇数,下一个idx也是奇数!!为了后面找后面边的反边,此时前面标号边数一定要构成一个偶数,即让下一条边标号为偶数。前面边数不够,只能虚拟一条边。*/if(idx&1) idx++;for(int i = 0; i < m2; i++){cin>>x>>y;add_edge(x,y,2);add_edge(y,x,2);}topSort();for(int i = 0; i < idx; i++){if(edge[i].val == 2)cout<<edge[i].from<<" "<<edge[i].to<<endl;}return 0;
}

Dizzy Cows(拓扑)相关推荐

  1. 洛谷P2017 [USACO09DEC]晕牛Dizzy Cows [拓扑排序]

    题目传送门 晕牛Dizzy Cows 题目背景 Hzwer 神犇最近又征服了一个国家,然后接下来却也遇见了一个难题. 题目描述 The cows have taken to racing each o ...

  2. P2017 [USACO09DEC]晕牛Dizzy Cows

    图论日常不会系列... 题意:给定有向边和无向边,然后给每一条无向边定向,使得到的图无环. 我本来想缩一下点的,但是越想越晕. 然后就翻了题解,恍然大悟... 其实只需要给只有有向边的图跑一次topo ...

  3. [DP魔炼][DP] DP随练随学(疯狂A题训练——DP基础篇 题解 下)

    终于写完啦!!!!!!!! T28 最大子段和 传送门 维护前缀和 找前面最小的 #include<bits/stdc++.h> using namespace std; #define ...

  4. HDU 3342 Legal or Not(拓扑排序)

    描述 ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that ju ...

  5. 【HDU - 3342】Legal or Not(拓扑排序)

    题干: ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that j ...

  6. Milking Order(拓扑+二分+优先队列)

    Milking Order 时间限制: 3 Sec  内存限制: 128 MB                                                             ...

  7. 【图论】有向无环图的拓扑排序

    1. 引言 有向无环图(Directed Acyclic Graph, DAG)是有向图的一种,字面意思的理解就是图中没有环.常常被用来表示事件之间的驱动依赖关系,管理任务之间的调度.拓扑排序是对DA ...

  8. 视觉导航的神经拓扑SLAM

    视觉导航的神经拓扑SLAM Neural Topological SLAM for Visual Navigation 论文地址: http://openaccess.thecvf.com/conte ...

  9. vue 拓扑组件_Authing 登录组件优化实践解析

    Authing Guard 是一种可嵌入的登录表单,可根据你的需求进行配置,它使你可以轻松添加各种社会化登录方式,以便你的用户可以无缝登录,并且在不同平台拥有一致的登录体验. Authing 2.0 ...

最新文章

  1. Zabbi监控系统搭建
  2. python myqr 二维码生成
  3. 【Android WebSocket】Android 端 WebSocket 基本用法 ( 下载 Java-WebSocket源码 | 导入 Java-WebSocket-1.5.2 工程作为依赖 )
  4. Java队列 Queue
  5. SAP用户出口(exit)问题--数据源增强
  6. WPF插件开发:使用FrameworkElementAdapters时VS报错的问题
  7. BZOJ1016:[JSOI2008]最小生成树计数——题解
  8. 中海达数据怎么转rinex_cors账号网最新实战教程,中海达 F61 Plus RTK连接千寻cors账号的方法...
  9. 【BZOJ2251】[2010Beijing Wc]外星联络 后缀数组
  10. 六、Python之三元表达式、列表推导式、生成器表达式
  11. 吴恩达机器学习 2.矩阵和向量知识
  12. linux 2.6 内核的移植
  13. python基础之列表、元组
  14. pytest框架(三)
  15. c语言入门手机自学软件,C语言入门学习
  16. [Accessibility] ****************** Loading GAX Client Bundle ****************
  17. pinpoint全链路监控安装部署(支持dubbo)
  18. 程序员为什么要学习软件工程
  19. ACL+SASL的认证配置后的Kafka命令操作(Windows版)
  20. uni-app 157发布朋友圈-批量上传图片

热门文章

  1. linux2.6添加新硬盘,Linux_TurboLinux11添加新硬盘方法,一.Linux的硬盘识别2.6 kernel - phpStudy...
  2. 有向图的广度优先遍历_图的两种遍历方式
  3. 三十一、电子商务分析与服务推荐
  4. Python 中最黑魔法、最难懂的概念
  5. 26岁,发25篇SCI,当上211教授、博导。
  6. GitHub 标星 5000+!学生党学编程,有这份资料就够了!
  7. 系统超时或者服务器会话丢失,第 17 章 配置 Web 服务器(Undertow)
  8. python if和while的区别_python基础--while循环和if判断、基本运算符
  9. 502 bad gateway php-fm,php+nginx 上传大文件 502 Bad Gateway
  10. 批处理 操作mysql_用批处理对MySQL进行数据操作