HDU 1285 确定比赛名次(三种模板,用二维数组,队列,邻接表)
2016-08-05 11:20
399 查看
确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 22252 Accepted Submission(s): 8965
[align=left]Problem Description[/align]
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
[align=left]Input[/align]
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
[align=left]Output[/align]
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
[align=left]Sample Input[/align]
4 3
1 2
2 3
4 3
[align=left]Sample Output[/align]
1 2 4 3
用二维数组记录两者之间的关系(用c++编译错误用G++提交);
代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int map[510][510];//map[i][j]记录i与j两者之间的关系; int queue[510];// int indegree[510];//indegree[i]表示i的入度,前驱数量; int topo(int n) { int i,j,k,t=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(indegree[j]==0)//每次找出前驱数量为0的点,即每次找到第一名; { k=j; break; } } queue[t++]=k; indegree[k]=-1;//将找到的前驱数量为0的点入度设为-1; for(int j=1;j<=n;j++) { if(map[k][j]) indegree[j]--;//第二步将前驱中与第一名有关系的点入度减1; } } printf("%d",queue[0]);//输出拓扑排序; for(int i=1;i<n;i++) { printf(" %d",queue[i]); } printf("\n"); } int main() { int n,m,a,b; while(scanf("%d%d",&n,&m)!=EOF) { memset(map,0,sizeof(map)); memset(indegree,0,sizeof(indegree)); for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); if(map[a][b]==0)//避免重复的数据输入; { map[a][b]=1;//第一步记录关系和点的前驱数量 ; indegree[b]++; } } topo(n); } return 0; }用队列做:
#include<string.h> #include<stdio.h> #include<queue> #include<algorithm> using namespace std; int map[510][510]; int indegree[510]; int topo(int n) { int i,j; priority_queue<int,vector<int>,greater<int> >Q; for(i=1;i<=n;i++) { if(indegree[i]==0) Q.push(i); } int sign=1; while(!Q.empty()) { int top=Q.top(); Q.pop(); indegree[top]=-1; if(sign) printf("%d",top); else printf(" %d",top); sign=0; for(j=1;j<=n;j++) { if(map[top][j]) { indegree[j]--; if(indegree[j]==0) Q.push(j); } } } printf("\n"); } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(map,0,sizeof(map)); memset(indegree,0,sizeof(indegree)); for(int i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); if(map[a][b]==0) { map[a][b]=map[b][a]=1; indegree[b]++; } } topo(n); } return 0; }用临界表的方法存储关系;
代码:
#include<stdio.h> #include<string.h> int head[2500]; int queue[2500]; int num; int indegree[510]; struct node { int to,next; }a[2510]; void init() { memset(head,-1,sizeof(head)); memset(indegree,0,sizeof(indegree)); num=0; } void add(int x,int y) { a[num].to=y; //或者写成node E={y,head[x]}; a[num].next=head[x];// a[num]=E; head[x]=num++; indegree[y]++; } int topo(int n) { int i,j,k,t=0; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(indegree[j]==0) { k=j; break; } } queue[t++]=k; indegree[k]=-1; for(j=head[k];j!=-1;j=a[j].next) { int m=a[j].to; indegree[m]--; } } printf("%d",queue[0]); for(int i=1;i<n;i++) { printf(" %d",queue[i]); } printf("\n"); } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { init(); for(int i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b); } topo(n); } return 0; }
相关文章推荐
- 【HDU】-1285-确定比赛名次(拓扑排序)(二维数组||邻接表||队列)
- 拓扑排序模板-优先队列 hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次 拓扑排序模板题 优先队列
- HDU 1285--确定比赛名次【拓扑排序 && 邻接表实现】
- HDU 1285 确定比赛名次 拓扑排序模板题
- hdu 1285 确定比赛名次 简单的拓扑排序模板题~~需要注意重边
- hdoj 1285 确定比赛名次 ( 拓扑排序--三种模板 )
- HDU 1285 拓普排序 基本模板例题 确定比赛名次
- HDU-1285-确定比赛名次-拓扑排序(模板)
- HDU 1285 确定比赛名次(拓扑排序的三种实现方法)
- HDU 1285 确定比赛名次(拓扑排序&amp;&amp;优先队列优化)
- hdu 1285 确定比赛名次 (浙大拓扑排序模板)
- HDU 1285--确定比赛名次【拓扑排序 && 邻接表实现】
- HDU-1285-确定比赛名次【拓扑排序模板】
- 确定比赛名次(hdu-1285)(拓扑排序队列实现)
- [HDU](1285)确定比赛名次 ---拓扑排序+STL优先级队列(图)
- hdu 1285 确定比赛名次
- 拓扑排序模版--hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次(很典型的拓扑排序)
- hdu 1285 确定比赛名次