拓扑排序

本文介绍了一种使用拓扑排序解决比赛胜负问题的方法。在只知道两两参赛者胜负的情况下,通过建立有向无环图并对其进行拓扑排序,可以确定最终的总胜负。文章详细解释了拓扑排序的概念,并提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接。题目大意:一个很实际的问题,比赛中只知道两两参赛者的胜负,确定总的胜负。这个问题其实有很多中写法,模拟也是可以的。但是最经典的写法我觉得还是使用拓扑排序来做。

图的拓扑排序其实就是给图的每一个顶点编号,使用一种规则将图的顶点有序的输出,这就是图的拓扑排序。这是对有向无环图来说的,其实这个应用有很多种,比如图的判环,只有无环图才能完成拓扑排序。又比如时间的安排,比赛名次的确定,实际上我们都知道,对于完成一件事情可以分解成不同的小的步骤,这些小的步骤的完成也是有先后顺序的。比如我们必须先穿完裤子再穿鞋子等等。利用这种关系我们可以建图,然后对图进行拓扑排序就可以知道每一个事情的先后顺序。拓扑排序思想很简单主要分为两步:(1)在图中的每一个顶点中寻找入度为0的点,删除这个点的所有边。(2)重复(1)整张图被删除。

下面出给这个具体实现的代码以及必要的解释:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 600;
int M[maxn][maxn];
int in[maxn];//入度数组
int ans[maxn];
int n, m;
void init()
{
	memset(M, 0, sizeof(M));
	memset(in, 0, sizeof(in));
	memset(ans, 0, sizeof(ans));
}
void solve()
{
	init();
	int x, y;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d", &x, &y);
		if (M[x][y] == 0)//这里需要考虑重边的情况
		{
			in[y]++;
			M[x][y] = 1;
		}
	}
	for (int i = 1; i <= n; i++)
	{
		int k = 1;
		while (in[k] != 0)k++;//寻找当前入度为0的顶点
		ans[i] = k;//这个时候ans=k
		in[k] = -1;//删除这这个顶点
		//删除与这个顶点相连的所有边
		for (int i = 1; i <= n; i++)
		{
			if (M[k][i] == 1)
			{
				in[i]--;
			}
		}
	}
	for (int i = 1; i < n; i++)
	{
		printf("%d ", ans[i]);
	}
	printf("%d\n",ans[n]);
}
int main()
{
	while (~scanf("%d%d", &n, &m))
	{
		solve();
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值