# floyd算法(多源最短路径) python实现

Floyd(弗洛伊德)算法用来找每个点两两之间的最短距离（多源最短路径），是典型的动态规划

1. 直接到达( i --> j )
2. 通过走其他点(k1, k2 … kn)，一个或多个点到达（ i --> k1–>k2–> … --> j )

graph[ i ][ j ] = min ( graph[ i ][ j ]， graph[ i ][ 1 ] + graph[ 1 ][ j ] )

for i in range(n):
for j in range(n):
graph[i][j] = min(graph[i][j], graph[i][1] + graph[1][j])


for i in range(n):
for j in range(n):
graph[i][j] = min(graph[i][j], graph[i][2] + graph[2][j])


for k in range(n):
for i in range(n):
for j in range(n):
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])


import sys

sys.setrecursionlimit(100000000)

# 弗洛伊德算法
def floyd():
n = len(graph)
for k in range(n):
for i in range(n):
for j in range(n):
if graph[i][k] + graph[k][j] < graph[i][j]:
graph[i][j] = graph[i][k] + graph[k][j]
parents[i][j] = parents[k][j]  # 更新父结点

# 打印路径
def print_path(i, j):
if i != j:
print_path(i, parents[i][j])
print(j, end='-->')

# Data [u, v, cost]
datas = [
[0, 1, 2],
[0, 2, 6],
[0, 3, 4],
[1, 2, 3],
[2, 0, 7],
[2, 3, 1],
[3, 0, 5],
[3, 2, 12],
]

n = 4

# 无穷大
inf = 9999999999

# 构图
graph = [[(lambda x: 0 if x[0] == x[1] else inf)([i, j]) for j in range(n)] for i in range(n)]
parents = [[i] * n for i in range(4)]  # 关键地方，i-->j 的父结点初始化都为i
for u, v, c in datas:
graph[u][v] = c	# 因为是有向图，边权只赋给graph[u][v]
#graph[v][u] = c # 如果是无向图，要加上这条。

floyd()

print('Costs:')
for row in graph:
for e in row:
print('∞' if e == inf else e, end='\t')
print()

print('\nPath:')
for i in range(n):
for j in range(n):
print('Path({}-->{}): '.format(i, j), end='')
print_path(i, j)
print(' cost:', graph[i][j])

# 最终的graph
# graph[i][j]表示i-->j的最短路径
# 0	2	5	4
# 9	0	3	4
# 6	8	0	1
# 5	7	10	0
#
# Path:
# Path(0-->0): 0--> cost: 0
# Path(0-->1): 0-->1--> cost: 2
# Path(0-->2): 0-->1-->2--> cost: 5
# Path(0-->3): 0-->3--> cost: 4
# Path(1-->0): 1-->2-->3-->0--> cost: 9
# Path(1-->1): 1--> cost: 0
# Path(1-->2): 1-->2--> cost: 3
# Path(1-->3): 1-->2-->3--> cost: 4
# Path(2-->0): 2-->3-->0--> cost: 6
# Path(2-->1): 2-->3-->0-->1--> cost: 8
# Path(2-->2): 2--> cost: 0
# Path(2-->3): 2-->3--> cost: 1
# Path(3-->0): 3-->0--> cost: 5
# Path(3-->1): 3-->0-->1--> cost: 7
# Path(3-->2): 3-->0-->1-->2--> cost: 10
# Path(3-->3): 3--> cost: 0


12-19 1万+

09-20 4378
08-06 250
03-11 5883
05-11 1656
03-25 5747
02-06 1354
01-01 2万+
08-22
11-21 1191
03-11 7278
09-09 586
05-17 1146
06-30 96
02-27 459