确定比赛名次

题目大意

有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

分析

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

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

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=1005;
int head[maxn],ru[maxn],path[maxn];
int tot=1;
int n,m,cnt;
struct asd{
int from,to,next;
}b[maxn];
void ad(int aa,int bb){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
head[aa]=tot++;
}
struct jie{
int num;
jie(int aa=0){
num=aa;
}
bool operator < (const jie& A) const{
return num>A.num;
}
};
void solve(){
priority_queue<jie> q;
for(int i=1;i<=n;i++){
if(ru[i]==0) q.push(jie(i));
}
while(!q.empty()){
int xx=q.top().num;
q.pop();
path[++cnt]=xx;
for(int i=head[xx];i!=-1;i=b[i].next){
int u=b[i].to;
if(--ru[u]==0) q.push(jie(u));
}
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(head,-1,sizeof(head));
memset(b,0,sizeof(struct asd));
memset(ru,0,sizeof(ru));
memset(path,0,sizeof(path));
tot=1,cnt=0;
for(int i=1;i<=m;i++){
int aa,bb;
scanf("%d%d",&aa,&bb);
ad(aa,bb);
ru[bb]++;
}
solve();
for(int i=1;i<=cnt;i++){
if(i==1) printf("%d",path[i]);
else printf(" %d",path[i]);
}
printf("\n");
}
return 0;
}

逃生

题目描述

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

现在有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

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

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

大家注意意会

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=200005;
int head[maxn],ru[maxn],path[maxn];
int tot=1;
int n,m,cnt;
struct asd{
int from,to,next;
}b[maxn];
void ad(int aa,int bb){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
head[aa]=tot++;
}
struct jie{
int num;
jie(int aa=0){
num=aa;
}
bool operator < (const jie& A) const{
return num<A.num;
}
};
void solve(){
priority_queue<jie> q;
for(int i=1;i<=n;i++){
if(ru[i]==0) q.push(jie(i));
}
while(!q.empty()){
int xx=q.top().num;
q.pop();
path[++cnt]=xx;
for(int i=head[xx];i!=-1;i=b[i].next){
int u=b[i].to;
if(--ru[u]==0) q.push(jie(u));
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
memset(b,0,sizeof(struct asd));
memset(ru,0,sizeof(ru));
memset(path,0,sizeof(path));
tot=1,cnt=0;
for(int i=1;i<=m;i++){
int aa,bb;
scanf("%d%d",&aa,&bb);
ad(bb,aa);
ru[aa]++;
}
solve();
for(int i=cnt;i>=1;i--){
if(i==cnt) printf("%d",path[i]);
else printf(" %d",path[i]);
}
printf("\n");
}
return 0;
}

确定比赛名次 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. 一文了解Docker容器技术的操作

    一文了解Docker容器技术的操作 前言一.Docker是什么二.Docker的安装及测试Docker的安装Docker的Hello world测试三.Docker的常见操作镜像的基本操作容器的基本操 ...

  2. Okapi BM25算法

    引言 Okapi BM25,一般简称 BM25 算法,在 20 世纪 70 年代到 80 年代,由英国一批信息检索领域的计算机科学家发明.这里的 BM 是"最佳匹配"(Best M ...

  3. chattr +i 用户也没法随意删除

    root用户也没法用rm随意删除文件?   前言 在你的印象中,是不是root用户就可以为所欲为呢?随便一个rm -rf *,一波骚操作走人?可能没那么容易. 先来个示例,创建一个文本文件test.t ...

  4. 5分钟速成Markdown

    一.认识 Markdown Markdown 是一种用来写作的轻量级「标记语言」,它用简洁的语法代替排版,而不像一般我们用的字处理软件 Word 或 Pages 有大量的排版.字体设置.它使我们专心于 ...

  5. cnpm的安装(超级详细版)

    1. 安装node 打开黑窗口   安装node 网上教程很多,我就不加上了 2.node -v  查看node是否已安装 3.安装淘宝镜像 npm install -g cnpm -registry ...

  6. [转] strtol()详解

    点击此处阅读原文 今天,在review 一些代码的时候,看到了strtol()这个函数,由于以前使用它的时候,还没有深刻的了解,这次,我决定探个究竟. 网上关于这个函数的资料大都来源于同份资料,lin ...

  7. Pants On Fire(链式前向星存图、dfs)

    Pants On Fire 传送门:链接  来源:upc9653 题目描述 Donald and Mike are the leaders of the free world and haven't ...

  8. 青蛙的约会 (ax+by=c求最小整数解)【拓展欧几里得】

                                                  青蛙的约会(点击跳转) 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住 ...

  9. UWP实现第二字幕并且跟随系统的设置

    话不多说,先看一下最终效果 系统设置默认 在系统设置里面更改字幕的显示效果 需求 要求播放器可以显示第二字幕,类似旁白的文字解释.比如片中出现了一个专业术语,这个时候观众可能有些疑惑.所以需要在屏幕上 ...

  10. 在tp5.1中获取所有控制器的文件名和所有控制器下的方法名

    我在这块做的是下拉框改变控制器然后ajax去调用获取方法 上代码 private function redController(){//获取当前控制器目录下所有的文件名 $arr=scandir('. ...