前置知识: 算法与数据结构

Floyd-Warshall

00:00
2 min Intermediate 2026/6/14

Floyd-Warshall 多源最短路径算法:动态规划推导、路径重建、负环检测与传递闭包。

1. 算法原理

1.1 动态规划定义

1.2 状态转移

含义:要么不经过 ,要么经过 )。

1.3 空间优化

维可以省略,原地更新

def floyd_warshall(dist):
    n = len(dist)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                if dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]
    return dist

2. 路径重建

2.1 记录中间节点

def floyd_with_path(dist):
    n = len(dist)
    nxt = [[j if dist[i][j] < float('inf') else -1 for j in range(n)] for i in range(n)]

    for k in range(n):
        for i in range(n):
            for j in range(n):
                if dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]
                    nxt[i][j] = nxt[i][k]

    return dist, nxt

def reconstruct_path(nxt, i, j):
    if nxt[i][j] == -1:
        return []
    path = [i]
    while i != j:
        i = nxt[i][j]
        path.append(i)
    return path

3. 负环检测

3.1 检测方法

Floyd 完成后,如果 dist[i][i] < 0,则存在经过 的负

def has_negative_cycle(dist):
    n = len(dist)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                if dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]
    for i in range(n):
        if dist[i][i] < 0:
            return True
    return False

4. 传递闭包

4.1 可达性矩阵

将 Floyd 用于判断节点间是否可达:

def transitive_closure(reach):
    n = len(reach)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                reach[i][j] = reach[i][j] or (reach[i][k] and reach[k][j])
    return reach

4.2 位运算优化

def transitive_closure_bitwise(reach):
    n = len(reach)
    for k in range(n):
        for i in range(n):
            if reach[i] & (1 << k):
                reach[i] |= reach[k]
    return reach

5. 复杂度与应用

维度
时间
空间
适用源最短路

适用场景稠密图、需要所有节点对最短路、负权(无负)。

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式