确定比赛名次

题目大意

有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。

Input

输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。

Output

给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。

其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。

样例

Sample Input

4 3

1 2

2 3

4 3

Sample Output

1 2 4 3

分析

比较裸的拓扑排序的题,唯一需要考虑的就是输出的顺序

不过这个也不难,用一个优先队列存一下就可以了

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<queue>
  6. using namespace std;
  7. const int maxn=1005;
  8. int head[maxn],ru[maxn],path[maxn];
  9. int tot=1;
  10. int n,m,cnt;
  11. struct asd{
  12. int from,to,next;
  13. }b[maxn];
  14. void ad(int aa,int bb){
  15. b[tot].from=aa;
  16. b[tot].to=bb;
  17. b[tot].next=head[aa];
  18. head[aa]=tot++;
  19. }
  20. struct jie{
  21. int num;
  22. jie(int aa=0){
  23. num=aa;
  24. }
  25. bool operator < (const jie& A) const{
  26. return num>A.num;
  27. }
  28. };
  29. void solve(){
  30. priority_queue<jie> q;
  31. for(int i=1;i<=n;i++){
  32. if(ru[i]==0) q.push(jie(i));
  33. }
  34. while(!q.empty()){
  35. int xx=q.top().num;
  36. q.pop();
  37. path[++cnt]=xx;
  38. for(int i=head[xx];i!=-1;i=b[i].next){
  39. int u=b[i].to;
  40. if(--ru[u]==0) q.push(jie(u));
  41. }
  42. }
  43. }
  44. int main(){
  45. while(scanf("%d%d",&n,&m)!=EOF){
  46. memset(head,-1,sizeof(head));
  47. memset(b,0,sizeof(struct asd));
  48. memset(ru,0,sizeof(ru));
  49. memset(path,0,sizeof(path));
  50. tot=1,cnt=0;
  51. for(int i=1;i<=m;i++){
  52. int aa,bb;
  53. scanf("%d%d",&aa,&bb);
  54. ad(aa,bb);
  55. ru[bb]++;
  56. }
  57. solve();
  58. for(int i=1;i<=cnt;i++){
  59. if(i==1) printf("%d",path[i]);
  60. else printf(" %d",path[i]);
  61. }
  62. printf("\n");
  63. }
  64. return 0;
  65. }

逃生

题目描述

糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。

现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。

同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。

负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。

那么你就要安排大家的顺序。我们保证一定有解。

Input

第一行一个整数T(1 <= T <= 5),表示测试数据的个数。

然后对于每个测试数据,第一行有两个整数n(1 <= n <= 30000)和m(1 <= m <= 100000),分别表示人数和约束的个数。

然后m行,每行两个整数a和b,表示有一个约束a号必须在b号之前。a和b必然不同。

Output

对每个测试数据,输出一行排队的顺序,用空格隔开。

样例

Sample Input

1

5 10

3 5

1 4

2 5

1 2

3 4

1 4

2 3

1 5

3 5

1 2

Sample Output

1 2 3 4 5

分析

乍看上去,是不是两道题完全一样

确实,我一开始也是这么想的,而且样例也能过

但是交上去确是WA

为了更好地理解两道题,我们来用同样的数据举一个例子

对于第一道题

我们假设3号队伍的排名要高于1号队伍,同时2号队伍的排名要高于4号队伍

这样,我们就可以建两条边

3---->1 2---->4

用第一题的方法得到的拓扑排序为2 3 1 4

是我们想要的结果

但对于第二道题,我们用同样的方法,得到的拓扑排序为2 3 1 4

但是显然这不是最优方案,因为我们要尽可能满足1号在2号前面

所以还有一种更优的排序为3 1 2 4

这样,两种顺序的区别就显而易见了

那么我们应该怎么办呢,倒序建图就可以了

大家注意意会

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<queue>
  6. using namespace std;
  7. const int maxn=200005;
  8. int head[maxn],ru[maxn],path[maxn];
  9. int tot=1;
  10. int n,m,cnt;
  11. struct asd{
  12. int from,to,next;
  13. }b[maxn];
  14. void ad(int aa,int bb){
  15. b[tot].from=aa;
  16. b[tot].to=bb;
  17. b[tot].next=head[aa];
  18. head[aa]=tot++;
  19. }
  20. struct jie{
  21. int num;
  22. jie(int aa=0){
  23. num=aa;
  24. }
  25. bool operator < (const jie& A) const{
  26. return num<A.num;
  27. }
  28. };
  29. void solve(){
  30. priority_queue<jie> q;
  31. for(int i=1;i<=n;i++){
  32. if(ru[i]==0) q.push(jie(i));
  33. }
  34. while(!q.empty()){
  35. int xx=q.top().num;
  36. q.pop();
  37. path[++cnt]=xx;
  38. for(int i=head[xx];i!=-1;i=b[i].next){
  39. int u=b[i].to;
  40. if(--ru[u]==0) q.push(jie(u));
  41. }
  42. }
  43. }
  44. int main(){
  45. int t;
  46. scanf("%d",&t);
  47. while(t--){
  48. scanf("%d%d",&n,&m);
  49. memset(head,-1,sizeof(head));
  50. memset(b,0,sizeof(struct asd));
  51. memset(ru,0,sizeof(ru));
  52. memset(path,0,sizeof(path));
  53. tot=1,cnt=0;
  54. for(int i=1;i<=m;i++){
  55. int aa,bb;
  56. scanf("%d%d",&aa,&bb);
  57. ad(bb,aa);
  58. ru[aa]++;
  59. }
  60. solve();
  61. for(int i=cnt;i>=1;i--){
  62. if(i==cnt) printf("%d",path[i]);
  63. else printf(" %d",path[i]);
  64. }
  65. printf("\n");
  66. }
  67. return 0;
  68. }

确定比赛名次 UDU-1285 + 逃生 UDU 4857 拓扑排序(找不同)的更多相关文章

  1. HDU 4857 拓扑排序 优先队列

    n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移.输出序列 大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得 ...

  2. (拓扑)确定比赛名次 -- hdu -- 1285

    http://acm.hdu.edu.cn/showproblem.php?pid=1285 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  3. Day4 - G - 确定比赛名次 HDU - 1285

    有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道 ...

  4. HDU 4857 逃生 (反向拓扑排序 & 容器实现)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  5. 确定比赛名次 HDU - 1285 (拓扑排序)

     注意点: 输入数据中可能有重复,需要进行处理! #include <stdio.h> #include <iostream> #include <cstring> ...

  6. HDU 4857 逃生(反向拓扑排序)

    传送门 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社 ...

  7. HDU 4857 逃生(反向拓扑排序+优先队列)

    ( ̄▽ ̄)" //这题对序号输出有要求,较小的序号优先输出,所以用到优先队列 //优先队列是优先弹出值最大的,所以最后要反向输出结果,才是正确的output #include<iost ...

  8. HDU-4857 逃生(逆向拓扑排序)

    Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. ...

  9. 正向与反向拓扑排序的区别(hdu 1285 确定比赛名次和hdu 4857 逃生)

    确定比赛名次 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

随机推荐

  1. 温故知新-java多线程&深入理解线程池

    文章目录 摘要 java中的线程 java中的线程池 线程池技术 线程池的实现原理 简述 ThreadPoolExecutor是如何运行的? 线程池运行的状态和线程数量 任务执行机制 队列缓存 Wor ...

  2. Redis集群-主从模式

    1.架构设计 集群在单台主机上模拟搭建6个节点(3主3从的集群): 2.配置 创建与端口相同的文件夹存储Redis配置文件和持久化文件. 目录如下: 每个节点配置文件如下: 节点1: bind 192 ...

  3. 02.vue-router的进阶使用

    关键字:路由懒加载,全局导航守卫,组件导航守卫,redirect重定向,keep-alive,params,query 一.目录结构            二.index.js // 配置路由相关的信 ...

  4. 将XML转换为JSON并强制数组

    string xml = @"<person id='1'> <name>Alan</name> <url>http://www.google ...

  5. Java StringTokenizer 类使用方法,字符串分割

    Java StringTokenizer 属于 java.util 包,用于分隔字符串. StringTokenizer 构造方法: StringTokenizer(String str) :构造一个 ...

  6. [Computer Vision]Harris角点检测的详细推导

    Harris角点检测 思想 为什么要检测角点呢?因为角点的特征比较明显.进行角点检测的朴素思想是利用图像梯度,也就是根据图像强度的变化来寻找角点.如图所示 这里举了个例子,给定一个小的区域(Patch ...

  7. 如何通过PR给视频添加字幕?

    第一步:将视频通过导出音频格式MP3 第二步:将音频MP3导入网易见外平台 第三步:在网易见外平台创建项目,进行语音转写如下所示: 第四步:将从网易见外平台到处的srt字母文件,打开后进行编码为utf ...

  8. 分享一个我自己做的 Excel 万年历

    下载链接在此. 纯 Excel 公式实现,带农历,可自定义节日.配色. 带有紧凑日历和记事日历两种日历,均可直接 Ctrl+P 打印,且打印时不带有顶部的控制栏.

  9. Jmeter基础002----Jmeter简单使用

    一.Jmeter概述 1.概述 JMeter是Apache公司使用JAVA开发的一款开源测试工具,它的功能强大.高效,可以模拟一些高并发或多次循环等测试场景,使用方便灵活. 2.使用 安装配置java ...

  10. java中Proxy类初探

    在java中提供了一个动态代理类,这个类位于java.lang.reflect包中的Proxy类中.什么是动态代理类呢?就是可以在运行时创建一个实现了一组给定接口的新类.听上去有点高深的样子,其实是提 ...