HDU - 1285 确定比赛名次 拓扑排序 优先队列

Training 8 - B题

有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

#pragma warning (disable:4996)
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define inf 0X3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 500 + 5;
const int M = 1000 + 5;
const int maxn = 10000 + 5;

int head[N], ver[M], nex[N];
int deg[N];//入度
int a[N];//top序列
int tot;
int cnt;

int n, m;

void add(int x, int y)
{
	++tot;
	ver[tot] = y;
	nex[tot] = head[x];
	head[x] = tot;
	deg[y]++;
}

void topsort()
{
	priority_queue<int> q;
	for (int i = 1; i <= n; i++)
		if (deg[i] == 0)
			q.push(-i);
	while (q.size())
	{
		int x = -q.top();
		q.pop();
		a[++cnt] = x;
		for (int i = head[x]; i; i = nex[i])
		{
			int y = ver[i];
			if (--deg[y] == 0)
				q.push(-y);
		}
	}
}

int main()
{
	while (scanf("%d%d", &n, &m) != EOF)
	{
		memset(head, 0, sizeof(head));
		memset(ver, 0, sizeof(ver));
		memset(nex, 0, sizeof(nex));
		memset(deg, 0, sizeof(deg));
		tot = cnt = 0;
		for (int i = 1; i <= m; i++)
		{
			int u, v;
			scanf("%d%d", &u, &v);
			add(u, v);
		}
		topsort();
		for (int i = 1; i <= cnt; i++)
			if (i < cnt)
				printf("%d ", a[i]);
			else
				printf("%d\n", a[i]);
	}
	return 0;
}

思路:
拓朴排序的优先队列板子题。

发布了48 篇原创文章 · 获赞 0 · 访问量 808
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览