确定比赛名次

题目大意

有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. 总结:Jmeter常用参数化方式

    一.从CSV文件中读取 二.通过函数生成 三.用户自定义变量 四.用户参数 五.使用正则表达式提取 六.从数据库中读取

  2. CVE¬-2020-¬0796 漏洞复现(本地提权)

    CVE­-2020-­0796 漏洞复现(本地提权) 0X00漏洞简介 Microsoft Windows和Microsoft Windows Server都是美国微软(Microsoft)公司的产品 ...

  3. Android开发之StrictMode

    StrictMode简介 Android开发者官网对StrictMode的介绍 StrictMode类是Android 2.3(API 9)引入的一个工具类 用来帮助开发者发现代码中一些不规范的问题, ...

  4. [转载]java内存工具VisualVM的简单使用以及与Idea集成

    本文来源https://blog.csdn.net/KingBoyWorld/article/details/75579606 一.idea集成 1.打开设置 windows File->Set ...

  5. Math.round方法、String实例化

    math.round(11.5)==12 传入的值是11.5,通过math.round方法进行四舍五入变成12(把一个数字舍入为最接近的整数) string s = new string("xyz") ...

  6. pom.xml 文件详解

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  7. 在SpringMVC获取客户端传递的数据的方式

    在处理请求的方法中,加入相对应的形参,保证形参参数名和传递的数据的参数名保持一致,就能够自动赋值 value:当不满足赋值条件时,可以使用value属性,指定映射关系 required:设置形参是否必 ...

  8. 深浅拷贝 set集合

    数据类型的补充 编码转换 # s1 = '中国' # b1 = s1.encode('utf-8') # # print(b1)-------------->b'\xe4\xb8\xad\xe5 ...

  9. docker-mcr 助您全速下载 dotnet 镜像

    2018 年五月之后,微软将后续发布的所有 docker image 都推送到了 MCR (Miscrosoft Container Registry),但在中国大陆,它的速度实在是令人发指,本文将介 ...

  10. 9.实战交付一套dubbo微服务到k8s集群(2)之Jenkins部署

    1.下载Jenkins镜像打包上传harbor上 [root@hdss7- ~]# docker pull jenkins/jenkins:2.190. [root@hdss7- ~]# docker ...