📅  最后修改于: 2023-12-03 15:28:37.663000             🧑  作者: Mango
这是一道 GATE CS 2011 中的问题,它考察的是有向图的遍历和拓扑排序。题目描述如下:
给定一个有向图 G,它没有环,且顶点编号从 1 到 n,其中 n 是顶点数。同时给出 m 条边的信息,每条边用它的起点和终点表示,两个整数之间用空格分隔。假设 G 中的所有顶点都可以从顶点 1 到达。针对该有向无环图,编写一个程序,计算它的拓扑排序。
要求将排序结果以一行输出,每个数之间用空格隔开。如果有多个完全相同的解,输出其中任意一个即可。
5 4
1 2
1 5
2 3
2 4
1 2 4 3 5
对于有向无环图,它的拓扑排序实际上就是基于有向边的一个序列,满足在这个序列中,若边 (u, v) 存在,则 u 一定在 v 的前面。可以使用深度优先搜索(DFS)或广度优先搜索(BFS)实现拓扑排序,这里使用 DFS 实现。
首先,需要用一个邻接表(adjacency list)存储有向图的边信息,然后使用一个栈(stack)维护那些还未被访问到的顶点。对于每个未被访问到的顶点,进行一次 DFS 搜索,将它所能到达的所有顶点加入栈中。每个顶点对应的 DFS 搜索完成后,将该顶点从栈中弹出并输出。按照这个顺序输出,就得到了有向图的一个拓扑排序。
def topological_sort(n, edges):
"""
:param n: int, number of vertices
:param edges: List[Tuple[int, int]], list of edges
:return: List[int], the topological order of vertices
"""
# construct adjacency list
adj_list = [[] for _ in range(n)]
in_degrees = [0] * n
for u, v in edges:
adj_list[u-1].append(v-1)
in_degrees[v-1] += 1
# push vertices with in-degree 0 to stack
stack = [u for u in range(n) if in_degrees[u] == 0]
# topological sort using DFS and stack
topo_order = []
while stack:
u = stack.pop()
topo_order.append(u + 1)
for v in adj_list[u]:
in_degrees[v] -= 1
if in_degrees[v] == 0:
stack.append(v)
return topo_order
其中 n
是顶点数,edges
是边的信息(每条边用一个二元组表示)。这里使用了邻接表和入度表,以便在 DFS 过程中进行拓扑排序。最后将结果输出即可。
该算法的时间复杂度为 $O(N + M)$,其中 $N$ 是顶点数,$M$ 是边数。使用邻接表存储和更新图的边信息需要 $O(M)$ 的时间,DFS 遍历需要 $O(N)$ 的时间,因此总复杂度为 $O(N + M)$。时间复杂度在 GATE CS 2011 考试中并不是限制因素,因此可以放心使用。