确定比赛名次(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 }

 今天比赛这个题错了好多次。。。。

知道真相的我眼泪流了下来。。。

我没有判断重边。。。

代码:

#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;
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值