WEEK 8 B 猫猫向前冲

题目

众所周知, TT 是一位重度爱猫人士,他有一只神奇的魔法猫。
有一天,TT 在 B 站上观看猫猫的比赛。一共有 N 只猫猫,编号依次为1,2,3,…,N进行比赛。比赛结束后,Up 主会为所有的猫猫从前到后依次排名并发放爱吃的小鱼干。不幸的是,此时 TT 的电子设备遭到了宇宙射线的降智打击,一下子都连不上网了,自然也看不到最后的颁奖典礼。
不幸中的万幸,TT 的魔法猫将每场比赛的结果都记录了下来,现在他想编程序确定字典序最小的名次序列,请你帮帮他。

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

思路

猫的胜负关系可想象成有向图中的边,a胜b,即有由a指向b的边,这些点的拓扑序列即为最终的名次。要输出字典序最小的拓扑序列,因此可用一个最小堆来求出拓扑序列。

代码

#include <iostream>
#include <queue>
#include <algorithm>
#include <string.h>

using namespace std;

const int maxn = 505;
struct edge
{
	int to, next;
}e[maxn * 2];
int n, m, inde[maxn], head[maxn], tot;

void add(int x, int y)
{
	e[++tot].to = y;
	e[tot].next = head[x];
	head[x] = tot;
}

void toposort()
{
	priority_queue<int>q;
	while (!q.empty()) 
		q.pop();
	for (int i = 1; i <= n; i++)
		if (inde[i] == 0)
			q.push(-i);
	vector<int> ans;
	while (!q.empty()) 
	{
		int u = -q.top();
		q.pop();
		ans.push_back(u);
		for (int i = head[u]; i!=0; i = e[i].next)
			if (--inde[e[i].to] == 0)
				q.push(-e[i].to);
	}
	for (int i = 0; i < ans.size() - 1; i++)
		cout << ans[i] << " ";
	cout << ans[ans.size() - 1] << endl;
}

int main()
{
	while (scanf_s("%d%d",&n,&m)!=EOF) 
	{
		memset(head, 0, sizeof(head));
		memset(inde, 0, sizeof(inde));
		tot = 0;
		for (int i = 1; i <= m; i++) 
		{
			int a, b;
			scanf_s("%d%d", &a, &b);
			add(a, b);
			inde[b]++;
		}
		toposort();
	}
	return 0;
}
发布了32 篇原创文章 · 获赞 0 · 访问量 669

猜你喜欢

转载自blog.csdn.net/qq_43814559/article/details/105567864