import math
def Dijkstra(n,arcs): # 单源最短路算法
matrics = [[-1]* n for i in range(n)] # 初始化邻接矩阵
for arc in arcs: # arc:[i,j,value]
matrics[arc[0]][arc[1]] = arc[2]
print('邻接矩阵:')
for i in range(n): # 根据边和权重构造邻接矩阵
for j in range(n):
if i == j:
matrics[i][j] = 0
print('{:5d}'.format(matrics[i][j]),end = '')
print()
dist = [-1] * n # 初始化到0号结点的最短路径长度数组
flag = [0] * n # 初始化flag数组,flag数组表示该结点是否在"最短路径集合"里
path = [-1] * n # 初始化path数组,path数组表示在该结点到0结点的最短路径序列中的前驱结点编号
flag[0] = 1
dist[0] = 0
for i in range(1,n): # 初始化"最短路径集合",初始状态里面只有0结点
dist[i] = matrics[0][i]
if dist[i] != -1:
path[i] = 0
for i in range(n-1): # 依次将剩下n-1个结点纳入到"最短路径集合"中
Min = math.inf
t = -1
for j in range(1,n): # 选择"最短路径集合"外的距离结点0最近的结点,将其纳入其中
if dist[j] != -1 and not flag[j] and dist[j] < Min:
Min = dist[j]
t = j
dist[t] = Min
flag[t] = 1 # 将t结点纳入其中
for j in range(1,n): # 修改集合外的其他结点到0结点的距离值
if not flag[j]:
if matrics[t][j] != -1 and (matrics[t][j] + dist[t] < dist[j] or dist[j] == -1):
path[j] = t # 记录前驱结点编号
dist[j] = matrics[t][j] + dist[t]
print('所有结点到0结点的最短路径距离数组:')
print(dist)
print('最短路径中的前驱结点数组:')
print(path)
arcs = [[0,1,4],[0,2,6],[0,3,6],[1,2,1],[3,2,2],[1,4,7],[2,4,6],[2,5,4],[3,5,5],[5,4,1],[4,6,6],[5,6,8]]
n = 7
Dijkstra(n,arcs)
输出:
邻接矩阵:
0 4 6 6 -1 -1 -1
-1 0 1 -1 7 -1 -1
-1 -1 0 -1 6 4 -1
-1 -1 2 0 -1 5 -1
-1 -1 -1 -1 0 -1 6
-1 -1 -1 -1 1 0 8
-1 -1 -1 -1 -1 -1 0
所有结点到0结点的最短路径距离数组:
[0, 4, 5, 6, 10, 9, 16]
最短路径中的前驱结点数组:
[-1, 0, 1, 0, 5, 2, 4]