📅  最后修改于: 2023-12-03 14:50:47.083000             🧑  作者: Mango
这是国际空间研究组织 CS 2014 考试的第 56 个问题。这道问题涉及到了有向图和拓扑排序等知识。
给定一个有向无环图 (DAG),请你输出其拓扑排序。
输入文件的第一行包含两个整数 $n$ 和 $m$,表示图中有 $n$ 个节点和 $m$ 条边。
接下来 $m$ 行,每行包含两个整数 $a$ 和 $b$,表示存在一条从节点 $a$ 到节点 $b$ 的有向边。
输出一行,包含拓扑排序后的节点编号,每个编号之间用空格隔开。如果不存在拓扑排序,则输出 "Sandro fails." (不含引号)。
$1 \leqslant n \leqslant 10^5$,
$1 \leqslant m \leqslant 10^6$,
$1 \leqslant a,b \leqslant n$。
输入:
6 6
2 3
3 1
4 1
4 6
5 6
6 1
输出:
4 5 2 3 6 1
给定一个有向无环图,要求进行拓扑排序。我们可以使用 Kahn 算法来解决这个问题。
Kahn 算法的基本思想是,从 DAG 中选择一个入度为 0 的顶点并输出,然后删除这个顶点以及以它为起点的所有有向边。重复此过程,直到图中不再存在入度为 0 的顶点为止。如果此时输出的顶点数小于图的顶点数,则说明该图存在环。
Kahn 算法可以使用队列来实现,具体步骤如下:
下面是基于 Python 语言的 Kahn 算法实现代码:
from collections import deque
def topo_sort():
# 统计每个节点的入度
in_degree = [0] * (n + 1)
for a, b in edges:
in_degree[b] += 1
# 将所有入度为 0 的节点加入队列中
q = deque()
for i in range(1, n+1):
if in_degree[i] == 0:
q.append(i)
# 输出拓扑排序
res = []
while q:
cur = q.popleft()
res.append(cur)
for a, b in edges:
if a == cur:
in_degree[b] -= 1
if in_degree[b] == 0:
q.append(b)
if len(res) != n:
return "Sandro fails."
else:
return " ".join(map(str, res))
在上面的代码中,n
和 m
分别表示节点数和边数,edges
是一组 (a, b)
值组成的边集合。topo_sort
函数表示进行拓扑排序,并返回排序结果。在函数中,我们首先使用 in_degree
数组统计每个节点的入度,然后将所有入度为 0 的节点加入队列中。在遍历队列的过程中,对于当前节点,我们遍历所有以该节点为起点的边,将终点的入度减 1。如果减 1 后终点的入度变为 0,则将其加入队列中。最后我们判断输出的节点数是否等于图的节点数,如果相等则返回排序结果,否则返回 "Sandro fails."。