📅  最后修改于: 2023-12-03 14:58:21.845000             🧑  作者: Mango
本题是关于图的遍历的。给出一个有向图,求该图中从起点到终点的所有路径。
给定一个由 $n$ 个点和 $m$ 条边构成的有向图,每个点都有一个唯一标识符。请编写一个程序,找出从起点到终点的所有路径。
第一行包含两个整数 $n$ 和 $m$,表示点数和边数。接下来 $m$ 行,每行两个整数 $u$ 和 $v$,表示存在一条从 $u$ 到 $v$ 的有向边。
最后一行包含两个整数 $s$ 和 $t$,表示起点和终点的标识符。
按照字典序,将所有从起点到终点的路径以如下格式输出:
[起点标识符] -> [中间节点 1 标识符] -> [中间节点 2 标识符] -> ... -> [终点标识符]
输入:
4 6
1 2
1 3
2 3
2 4
3 4
1 4
输出:
1 -> 2 -> 3 -> 4
1 -> 2 -> 4
1 -> 3 -> 4
本题要求从起点到终点的所有路径,因此我们可以使用深度优先搜索(DFS)来遍历图,同时使用一个列表来记录当前已经走过的节点。对于每一个节点,我们将其加入当前已经走过的节点列表中,然后扩展到其能够到达的所有节点。如果找到了终点,就将当前的路径加入结果列表。
最后,我们将结果列表按照字典序排序,并且将每个路径输出即可。
from collections import defaultdict
def all_paths(graph, start, end):
# 结果列表
result = []
# 当前路径列表
path = [start]
# 使用 set 来记录已经经过的节点,防止重复经过
visited = set()
# 深度优先搜索
dfs(graph, start, end, path, visited, result)
# 按照字典序排序并输出
result.sort()
return [" -> ".join(map(str, path)) for path in result]
def dfs(graph, node, end, path, visited, result):
if node == end:
result.append(list(path))
return
for neighbor in graph[node]:
if neighbor not in visited:
visited.add(neighbor)
path.append(neighbor)
dfs(graph, neighbor, end, path, visited, result)
visited.remove(neighbor)
path.pop()
if __name__ == '__main__':
n, m = map(int, input().split())
graph = defaultdict(list)
for i in range(m):
u, v = map(int, input().split())
graph[u].append(v)
start, end = map(int, input().split())
print("\n".join(all_paths(graph, start, end)))
本题中使用深度优先搜索来遍历图,时间复杂度为 $O(2^m)$,其中 $m$ 表示边的数量。
由于我们需要遍历所有从起点到终点的路径,并且每条路径需要输出,因此空间复杂度为 $O(2^m)$。注意,这里的空间复杂度不是结果的数量,而是结果路径长度之和。