确定比赛名次(map+邻接表 邻接表 拓扑结构 队列+邻接表)

确定比赛名次

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 40   Accepted Submission(s) : 31

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

题解:拓扑结构,可以用N种方法;

代码一:拓扑结构模板

 1 #include<stdio.h>
 2 #include<string.h>
 3 const int MAXN=510;
 4 int N,M;
 5 int map[MAXN][MAXN];
 6 int que[MAXN],ans[MAXN];
 7 void topu(){int k,top=0,temp;
 8     for(int i=0;i<N;i++){
 9             temp=-1;
10         for(int j=1;j<=N;j++){
11             if(!que[j]){
12                     ans[top++]=j;
13                 que[j]=-1;
14                 k=j;
15             temp=0;
16                 break;
17             }
18         }
19         if(temp==-1)break;
20         for(int j=1;j<=N;j++){
21             if(map[k][j])que[j]--;
22         }
23     }
24     for(int i=0;i<top;i++){
25         if(i)printf(" ");
26         printf("%d",ans[i]);
27     }
28     puts("");
29 }
30 void initial(){
31     memset(map,0,sizeof(map));
32     memset(que,0,sizeof(que));
33 }
34 int main(){
35     int a,b;
36     while(~scanf("%d%d",&N,&M)){
37             initial();
38         while(M--){
39         scanf("%d%d",&a,&b);
40         if(!map[a][b]){
41             map[a][b]=1;
42             que[b]++;
43         }
44         }
45         topu();
46     }
47 return 0;
48 }

代码二:邻接表:

 1 #include<stdio.h>
 2 #include<string.h>
 3 const int MAXN=510;
 4 struct Node{
 5     int next,to;
 6 };
 7 Node edg[MAXN];
 8 int head[MAXN];
 9 int que[MAXN],ans[MAXN],top;
10 int N,M;
11 void topu(){int k;
12     for(int i=0;i<N;i++){
13             int temp=-1;
14         for(int j=1;j<=N;j++){
15             if(!que[j]){
16                 temp=0;
17                 k=j;
18                 que[j]=-1;
19                 ans[top++]=j;
20                 break;
21             }
22         }
23         if(temp==-1)break;
24         for(int j=head[k];j!=-1;j=edg[j].next){
25             que[edg[j].to]--;
26         }
27     }
28     for(int i=0;i<top;i++){
29         if(i)printf(" ");
30         printf("%d",ans[i]);
31     }
32     puts("");
33 }
34 void initial(){
35     memset(head,-1,sizeof(head));
36     memset(que,0,sizeof(que));
37     top=0;
38 }
39 int main(){int a,b;
40     while(~scanf("%d%d",&N,&M)){
41             initial();
42         for(int i=1;i<=M;i++){
43             scanf("%d%d",&a,&b);
44             edg[i].to=b;
45             edg[i].next=head[a];
46             head[a]=i;
47             que[b]++;
48         }
49         topu();
50     }
51 return 0;
52 }

代码三:map+邻接表;

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<map>
 4 using namespace std;
 5 const int MAXN=510;
 6 struct Node{
 7     int to,next;
 8 };
 9 int head[MAXN];
10 Node edg[MAXN];
11 int ans[MAXN],top;
12 int N,M;
13 map<int,int>mp;
14 void topu(){map<int,int>::iterator iter;
15             //for(iter=mp.begin();iter!=mp.end();iter++){
16               //  printf("%d %d\n",iter->first,iter->second);
17           //  }
18     for(int i=0;i<N;i++){
19         for(iter=mp.begin();iter!=mp.end();iter++){
20             if(!iter->second)break;
21         }
22         if(iter==mp.end())break;
23         mp.erase(iter);
24         ans[top++]=iter->first;
25         for(int j=head[iter->first];j!=-1;j=edg[j].next){
26             mp[edg[j].to]--;
27         }
28     }
29     for(int i=0;i<top;i++){
30         if(i)printf(" ");
31         printf("%d",ans[i]);
32     }
33     puts("");
34 }
35 void initial(){
36     memset(head,-1,sizeof(head));
37     top=0;
38     mp.clear();
39     for(int i=N;i>0;i--)mp[i]=0;
40 }
41 int main(){int a,b;
42     while(~scanf("%d%d",&N,&M)){
43             initial();
44         for(int i=0;i<M;i++){
45             scanf("%d%d",&a,&b);
46             edg[i].to=b;
47             edg[i].next=head[a];
48             head[a]=i;
49             mp[b]++;
50         }
51         topu();
52     }
53     return 0;

代码四:队列+邻接表;

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 const int MAXN=510;
 6 struct Node{
 7     int to,next;
 8 };
 9 int head[MAXN],que[MAXN];
10 Node edg[MAXN];
11 int ans[MAXN],top;
12 int N,M;
13 priority_queue<int,vector<int>,greater<int> >dl;
14 void topu(){
15         for(int j=1;j<=N;j++){
16             if(!que[j])dl.push(j);
17         }
18         while(!dl.empty()){
19             ans[top++]=dl.top();
20             int k=dl.top();
21             que[k]=-1;
22             dl.pop();
23             for(int j=head[k];j!=-1;j=edg[j].next){
24                 que[edg[j].to]--;
25                 if(!que[edg[j].to])dl.push(edg[j].to);
26             }
27         }
28     for(int i=0;i<top;i++){
29         if(i)printf(" ");
30         printf("%d",ans[i]);
31     }
32     puts("");
33 }
34 void initial(){
35     memset(head,-1,sizeof(head));
36     top=0;
37     memset(que,0,sizeof(que));
38     while(!dl.empty())dl.pop();
39 }
40 int main(){int a,b;
41     while(~scanf("%d%d",&N,&M)){
42             initial();
43         for(int i=0;i<M;i++){
44             scanf("%d%d",&a,&b);
45             edg[i].to=b;
46             edg[i].next=head[a];
47             head[a]=i;
48              que[b]++;
49         }
50         topu();
51     }
52     return 0;
53 }
时间: 2024-07-30 05:40:26

确定比赛名次(map+邻接表 邻接表 拓扑结构 队列+邻接表)的相关文章

HDU 1258 确定比赛名次 &amp;&amp;HDU 3342 Legal or Not 【临接表+拓扑排序】

HDU 1258 链接:click here HDU 3342 链接:click here 题意: 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 14142    Accepted Submission(s): 5667 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,

HDU 1285 确定比赛名次 拓扑排序(邻接矩阵 邻接表

确定比赛名次 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前.现在请你编程序确定排名. Input 输

HDU 1285--确定比赛名次【拓扑排序 &amp;amp;&amp;amp; 邻接表实现】

确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17134    Accepted Submission(s): 6789 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2.3,.... .N进行比赛.比赛结束后,裁判委员会要将全部參赛队伍从前往后依次排名,但如今裁判委员会不能

ACM:最短路,dijkstra,邻接表的建立,使用邻接表跟优先队列的dijkstra,Bellman-Ford,Floyd。。

(一)dijkstra,邻接矩阵 所有边权均为正,不管有没有环,求单个源点出发,到所有节点的最短路.该方法同时适用于有向图和无向图. #include <iostream> #include <string> #include <stack> using namespace std; const int MAXN = 1000; const int INF = 100000000; int n, m; int maze[MAXN][MAXN], vis[MAXN], d

杭州电子科技大学Online Judge 之 “确定比赛名次(ID1285)”解题报告

杭州电子科技大学Online Judge 之 "确定比赛名次(ID1285)"解题报告 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) Problem Description 有N个比赛队(1<=N<=500).编号依次为1,2,3,.....N进行比赛.比赛结束后.裁判委员会要将全部參赛队伍从前往后依次排名. 但如今裁判委员会不能直接获得每一个队的比赛成绩,仅仅知道每场比赛的结果.即P1赢P2,用P1.P2表示,排名时P

HDU 1285 确定比赛名次(拓扑排序模板)

题意还是比较容易理解的,关键要看到后面的:合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前: 思路:这道题就是拓扑排序的经典应用了,用队列做的考虑优先编号小的出队就可以了. 拓扑排序: 拓扑排序是对有向无回路图(DAG)顶点的一种排序,它使得如果存在从u到v的有向路径,那么满足序列中u在v前. 所以我们的算法可以描述为这样一个过程: 1.找到整个图中所有的度为0的点,将这些点压进队列(栈)中 2.从队列(栈)中取出一点,输出,将该点及它的边删除,找到它所指向的点,如果改点是一个原点(删

HDOJ 1285 确定比赛名次(拓扑排序,四种实现方法)

确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17294    Accepted Submission(s): 6888 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直

HDU 1285——确定比赛名次(拓扑排序入门)

确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 12182    Accepted Submission(s): 4861 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直

hdu1285 确定比赛名次 (拓扑排序)

确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 16782    Accepted Submission(s): 6659 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直