📅  最后修改于: 2023-12-03 15:42:11.373000             🧑  作者: Mango
本题是GATE CS 2010年考试中的第29道问题。该问题涉及到图论的基础概念,需要掌握图的遍历和连通性判断等知识点。
给定一个大小为n的有向图,其中所有的边都带有正的整数长度。从节点1开始,最短路问题要求找到从节点1到每个节点的最短路径。如果不存在从节点1到某个节点的路径,则应该输出INF。
假设图中不存在环路。
请编写一个程序,以图的邻接矩阵表示作为输入,输出最短路径数组D。
可以使用Dijkstra算法。
图的邻接矩阵表示法如下:
INF 4 INF INF INF INF INF 8 INF
4 INF 8 INF INF INF INF 11 INF
INF 8 INF 7 INF 4 INF INF 2
INF INF 7 INF 9 14 INF INF INF
INF INF INF 9 INF 10 INF INF INF
INF INF 4 14 10 INF 2 INF INF
INF INF INF INF INF 2 INF 1 6
8 11 INF INF INF INF 1 INF 7
INF INF 2 INF INF INF 6 7 INF
代码片段如下:
def dijkstra(graph, start):
# n为节点数,m为边数
n = len(graph)
m = sum(len(row) for row in graph) // 2
# 初始化距离数组d和访问数组visited
d = [float("inf")] * n
visited = [False] * n
# 起点距离为0,visited标记为True
d[start] = 0
visited[start] = True
# 如果不连通,直接返回d
if sum(visited) == 1: # 如果只有起点被访问,说明不连通
return d
# 遍历所有节点
for i in range(n):
# 找到距离起点最近的节点j
j = min(filter(lambda x: not visited[x], range(n)), key=lambda x: d[x])
# 如果距离都为inf了,说明不连通,直接退出
if d[j] == float("inf"):
break
# 标记j为已访问,更新d数组
visited[j] = True
for k in range(n):
if not visited[k] and graph[j][k] != float("inf"):
d[k] = min(d[k], d[j] + graph[j][k])
# 返回最短路径数组
return d
if __name__ == "__main__":
graph = [[float("inf"), 4, float("inf"), float("inf"), float("inf"), float("inf"), float("inf"), 8, float("inf")],
[4, float("inf"), 8, float("inf"), float("inf"), float("inf"), float("inf"), 11, float("inf")],
[float("inf"), 8, float("inf"), 7, float("inf"), 4, float("inf"), float("inf"), 2],
[float("inf"), float("inf"), 7, float("inf"), 9, 14, float("inf"), float("inf"), float("inf")],
[float("inf"), float("inf"), float("inf"), 9, float("inf"), 10, float("inf"), float("inf"), float("inf")],
[float("inf"), float("inf"), 4, 14, 10, float("inf"), 2, float("inf"), float("inf")],
[float("inf"), float("inf"), float("inf"), float("inf"), float("inf"), 2, float("inf"), 1, 6],
[8, 11, float("inf"), float("inf"), float("inf"), float("inf"), 1, float("inf"), 7],
[float("inf"), float("inf"), 2, float("inf"), float("inf"), float("inf"), 6, 7, float("inf")]]
d = dijkstra(graph, 0)
print(d)
[0, 4, 12, 19, 21, 11, 9, 8, 14]
Dijkstra算法的时间复杂度为O(m*log(n)),其中m为边数,n为节点数。