确定比赛名次

确定比赛名次

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 20   Accepted Submission(s) : 16
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)
题目大意:
输入 N,M,表示有N的点(1~N),和需要输入M条边,下面有M行,每一行输入A,B,表示A的优先级大于B。
问你根据所给的优先级排序,按优先级降序输出的点。
第一次做的时候,只会邻接矩阵,比较简单,不过复杂度会比较高,能够做的数据也不大。
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h> 
 4 int InD[505];            
 5 int Edge[505][505];      
 6 void MakeSet(int Len)     
 7 {
 8     int i;
 9     for(i=0;i<=Len;i++)
10         InD[i]=0;
11     return;
12 }
13 int ToPoSort(int n,int* ret)       
14 {
15     int i,j,k;
16     for(j=1;j<=n;j++)
17     {
18         for(i=1;i<=n;i++)
19             if(InD[i]==0)        
20             {
21                 InD[i]--;             
22                 ret[j]=i;               
23                 for(k=1;k<=n;k++)
24                     if(Edge[i][k]==1)      
25                         InD[k]--;       
26                 break;
27             }
28         if(i>n)break;
29     }
30     if(j-1==n)    
31         return 1;
32     else
33         return 0;
34 }
35 
36 int main()
37 {
38     int N,M,i,a,b,ID[505];
39     while(scanf("%d%d",&N,&M)!=EOF)    
40     {
41         if(N==0&&M==0)return;
42         MakeSet(N);
43         memset(Edge,0,sizeof(Edge));
44         memset(ID,0,sizeof(ID));
45         for(i=0;i<M;i++)
46         {
47             scanf("%d%d",&a,&b);
48             if(Edge[a][b]==0)           
49             {
50                 Edge[a][b]=1;          
51                 InD[b]++;            
52             }
53         }
54         if(ToPoSort(N,ID))
55             for(i=1;i<=N;i++)
56             {
57                 printf("%d",ID[i]);
58                 if(i!=N)putchar(32);
59             }
60         putchar(10);
61 
62     }
63     return 0;
64 }
View Code

修改:2015.5.28 第二次做,改成了邻接表的形式,大大的提高了程序的效率。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <map>
 5 #define MAX 505
 6 using namespace std;
 7 int InD[505];/*InD[i]记录点i的入度*/
 8 int First[MAX];/*First[i]头结点的第一条边的编号*/
 9 struct edge
10 {
11     int TO;/**/
12     int Next;/*下一条边的编号*/
13 }ID[3*MAX];
14 int SIGN;
15 void Add_E(int x,int y)/*添加点操作*/
16 {
17     ID[SIGN].TO=y;
18     InD[y]++;
19     ID[SIGN].Next=First[x];
20     First[x]=SIGN++;
21 }
22 int Jude(int x,int y)/*查找与X是否与Y相连*/
23 {
24     int i;
25     for(i=First[x];i!=0;i=ID[i].Next)   //查找与该点相关的点
26     {
27        if(ID[i].TO==y)return 0;
28     }
29     return 1;
30 }
31 int ToPoSort(int N,int Num[])/*拓扑排序,邻接表*/
32 {
33     int i,j,k;
34     for(j=0;j<N;j++)
35     {
36         for(i=1;i<=N;i++)
37         {
38             if(InD[i]==0)
39             {
40                 InD[i]--;
41                 Num[j]=i;
42                 for(k=First[i];k!=0;k=ID[k].Next)
43                 {
44                     InD[ID[k].TO]--;
45                 }
46                 break;
47             }
48         }
49         if(i>N)break;
50     }
51     if(j==N)return 1;
52     else return 0;
53 }
54 int main()
55 {
56     int M,N,i;
57     int Num[MAX];
58     while(scanf("%d%d",&N,&M)!=EOF)
59     {
60         int a,b;
61         if(M==0&&N==0)break;
62         for(i=1;i<=N;i++){First[i]=0;InD[i]=0;}
63         for(i=0,SIGN=1;i<M;i++)
64         {
65             scanf("%d%d",&a,&b);
66             if(Jude(a,b))   /*判断重边*/
67             {
68                 Add_E(a,b);
69             }
70         }
71         if(ToPoSort(N,Num))/*拓扑排序*/
72         {
73             for(i=0;i<N;i++)
74             {
75                 if(i!=0)putchar(32);
76                 printf("%d",Num[i]);
77             }putchar(10);
78         }
79     }
80     return 0;
81 }
View Code

 

posted @ 2014-08-22 14:00  Wurq  阅读(196)  评论(0编辑  收藏  举报