📜  门| GATE CS 2010 |问题29(1)

📅  最后修改于: 2023-12-03 15:42:11.373000             🧑  作者: Mango

门 | GATE CS 2010 | 问题29

本题是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为节点数。