确定比赛名次
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 ",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 }
今天比赛这个题错了好多次。。。。
知道真相的我眼泪流了下来。。。
我没有判断重边。。。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<vector> using namespace std; const int INF=0x3f3f3f3f; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x); const int MAXN=510; int que[MAXN],mp[MAXN][MAXN]; int ans[MAXN]; int N; priority_queue<int,vector<int>,greater<int> >dl; /*void topu(){ int a,k=0; while(!dl.empty())dl.pop(); for(int i=1;i<=N;i++) if(!que[i]){ dl.push(i); que[i]=-1; } while(!dl.empty()){ a=dl.top(); dl.pop(); que[a]=-1; ans[k++]=a; for(int i=1;i<=N;i++) if(mp[a][i]){ que[i]--; if(!que[i]) dl.push(i); } } for(int i=0;i<k;i++){ if(i)printf(" "); printf("%d",ans[i]); }puts(""); }*/ void topu(){ int k=0; for(int i=0;i<N;i++){ int a; for(int j=1;j<=N;j++){ if(!que[j]){ a=j;break; } } ans[k++]=a; que[a]=-1; for(int j=1;j<=N;j++){ if(mp[a][j])que[j]--; } } for(int i=0;i<k;i++){ if(i)printf(" "); printf("%d",ans[i]); }puts(""); } int main(){ int M,a,b; while(~scanf("%d%d",&N,&M)){ mem(que,0);mem(mp,0); for(int i=0;i<M;i++){ scanf("%d%d",&a,&b); if(!mp[a][b]){//****** mp[a][b]=1; que[b]++; } } topu(); } return 0; }