HDU 1285 确定比赛名次(拓扑排序的三种实现方法)

2023-12-13 20:08

本文主要是介绍HDU 1285 确定比赛名次(拓扑排序的三种实现方法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

确定比赛名次

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 22189    Accepted Submission(s): 8925


Problem Description
有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

Author
SmallBeer(CML)

Source
杭电ACM集训队训练赛(VII)

Recommend
lcy   |   We have carefully selected several similar problems for you:   2647  3342  1811  1548  1874 



简单的拓扑排序模板题目。


代码:二维数组实现

#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;
const int MYDD=1103;
const int MAXDD=512;int ANS[MYDD];//存储答案
int indegree[MAXDD];
int map[MAXDD][MAXDD];
void Topo(int x) {//拓扑排序二维数组int now;//记录当前入度为 0 的节点int t=1;for(int i=1; i<=x; i++) {for(int j=1; j<=x; j++) {if(!indegree[j]) {now=j;break;}}ANS[t++]=now;indegree[now]=-1;//防止重复遍历for(int j=1; j<=x; j++) {if(map[now][j])indegree[j]--;//将前驱中含有第 now 名点的前驱数量减1}}
}int main() {int n,m;while(scanf("%d%d",&n,&m)!=EOF) {memset(indegree,0,sizeof(indegree));memset(map,0,sizeof(map));while(m--) {int a,b;scanf("%d%d",&a,&b);if(!map[a][b]) { //防止重复性的输入数据map[a][b]=1;indegree[b]++;}}Topo(n);for(int j=1; j<=n-1; j++)printf("%d ",ANS[j]);printf("%d\n",ANS[n]);}return 0;
}


代码:邻接表的实现(没有初始化,导致错误一次)

#include<stdio.h>
#include<string.h>
const int MYDD=1103;
const int MAXDD=5120;int indegree[MYDD];//保存节点入度
int edgenum;//边的总数
int head[MYDD];//标记节点"头指针"
void init() {memset(head,-1,sizeof(head));memset(indegree,0,sizeof(indegree));edgenum=0;
}
struct EDGE {//边的信息int v,next;
} edge[MAXDD*8];void addedge(int a,int b) {//边的增加EDGE T= {b,head[a]};edge[edgenum]=T;head[a]=edgenum++;indegree[b]++;
}int ANS[MAXDD];
void Topo(int x) {//构造排序int now,t=1;for(int j=1; j<=x; j++) {for(int i=1; i<=x; i++) {if(!indegree[i]) {now=i;break;}}ANS[t++]=now;indegree[now]=-1;for(int i=head[now]; i!=-1; i=edge[i].next) {int temp=edge[i].v;indegree[temp]--;}}
}int main() {int n,m;while(scanf("%d%d",&n,&m)!=EOF) {init();while(m--) {int a,b;scanf("%d%d",&a,&b);addedge(a,b);}Topo(n);//进行拓扑排序for(int j=1; j<=n-1; j++)//输出结果printf("%d ",ANS[j]);printf("%d\n",ANS[n]);}return 0;
}

代码:优先队列的实现

#include<stdio.h>
#include<string.h>
#include<queue>
#include<functional>
using namespace std;
const int MYDD=1103;
const int MAXDD=512;int indegree[MAXDD];//保存节点入度
int map[MAXDD][MAXDD];
int ans[MAXDD];
//优先队列的实现 
void Topo(int x) {priority_queue<int,vector<int>,greater<int> > Q;if(!Q.empty())Q.pop();//队列的清空for(int j=1; j<=x; j++) {if(!indegree[j]) Q.push(j);}int dd=1;while(!Q.empty()) {//队列非空持续进行 int now=Q.top();//取出当前排名 Q.pop();indegree[now]=-1;ans[dd++]=now;for(int j=1; j<=x; j++) {if(map[now][j]) {indegree[j]--;//和当前排名有关联的节点度数 -1 if(!indegree[j])Q.push(j);}}}
}int main() {int n,m;while(scanf("%d%d",&n,&m)!=EOF) {memset(indegree,0,sizeof(indegree));memset(map,0,sizeof(map));while(m--) {int a,b;scanf("%d%d",&a,&b);if(!map[a][b])map[a][b]=1,indegree[b]++;}Topo(n);//进行拓扑排序for(int j=1; j<n; j++)//输出结果printf("%d ",ans[j]);printf("%d\n",ans[n]);}return 0;
}



后:

话说,学姐讲的不是很快,挺好的微笑

********************************************


这篇关于HDU 1285 确定比赛名次(拓扑排序的三种实现方法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/489800

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操