[题解] hdu 1285 确定比赛名次 (BFS)

- 传送门 -

 http://acm.hdu.edu.cn/showproblem.php?pid=1285
 

# 确定比赛名次

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 28728    Accepted Submission(s): 11442

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

Source

杭电ACM集训队训练赛(VII)

- 题意 -

 给出 n 个队, m 个比赛的输赢关系. (前者胜后者)
 求这 n 个队的排名.
 

- 思路 -

 拓扑排序模板.
 
 细节见代码.
 
 PS :
 有重复边.
 

- 代码 -

#include<cstdio>
#include<cstring>
using namespace std;

const int N = 505;

int IN[N];
int MAP[N][N];
int n, m;

void topo() {
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j) {
			if (IN[j] == 0) {
				printf("%d", j);
				if (i != n) printf(" ");
				IN[j] --;
				for (int k = 1; k <= n; ++k)
					if (MAP[j][k])
						IN[k] --;
				break;
			}
		}
	printf("\n");
}

int main() {
	while (~scanf("%d%d", &n, &m)) {
		memset(IN, 0, sizeof (IN));
		memset(MAP, 0, sizeof (MAP));
		for (int i = 1; i <= m; ++i) {
			int x, y;
			scanf("%d%d", &x, &y);
			if (!MAP[x][y]) IN[y] ++; //重复边
			MAP[x][y] = 1;
		}
		topo();
	}
	return 0;
}
posted @ 2017-08-20 17:03  lstttt  阅读(187)  评论(0编辑  收藏  举报