多源最短路径
多源最短路不是“多个起点一起跑”,而是要得到任意两点之间的最短距离;这通常意味着你要维护一整张距离矩阵。
核心概念
多源最短路径:求所有顶点对之间的最短路径。
Floyd-Warshall算法:
- 时间复杂度:O(V³)
- 空间复杂度:O(V²)
- 适用:稠密图、所有点对最短路径
为什么一般想到 Floyd-Warshall
因为它最适合回答这种问题:
我不是只关心一个起点,而是关心任意 i 到任意 j 的最短路。如果把单源最短路算法重复跑很多次当然也能做,但当图规模不大、问题就是“全对全”时,Floyd-Warshall 的矩阵写法更直接。
经典应用
算法特点
优点:
- 简洁易懂,代码短
- 能处理负权边(但不能有负环)
- 一次计算得到所有点对最短路径
缺点:
- 时间复杂度高O(V³)
- 不适合大规模稀疏图
使用场景:
- 图的规模较小(V < 500)
- 需要所有点对的最短路径
- 图比较稠密
Go 代码
func floydWarshall(graph [][]int) [][]int {
n := len(graph)
dist := make([][]int, n)
for i := range dist {
dist[i] = make([]int, n)
copy(dist[i], graph[i])
}
for k := 0; k < n; k++ {
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if dist[i][k]+dist[k][j] < dist[i][j] {
dist[i][j] = dist[i][k] + dist[k][j]
}
}
}
}
return dist
}易错点
多源最短路最容易错的地方,不是三重循环,而是初始化和无穷大处理。
dist[i][i]必须初始化为0。- 不连通边要统一初始化成足够大的
inf。 - 做加法前要先判断两段是不是都可达,避免
inf + inf这类溢出逻辑。 - 如果图很稀疏、点很多,
O(V^3)往往不现实。
返回:图算法