算法简介
可以解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题
算法的时间复杂度为 O ( N 3 ) O(N^3) O(N3),空间复杂度为 O ( N 2 ) O(N^2) O(N2)。
与迪杰斯特拉算法不同的是,迪杰斯特拉算法只能求单源最短路径,并且不能处理负权边
算法思想
动态规划的思想
设 D i , j , k D_{i, j, k} Di,j,k 为从 i i i 到 j j j 的只以 ( 1.. k ) (1 . . k) (1..k) 集合中的节点为中间节点的最短路径的长度。
- 若最短路径经过点k, 则 D i , j , k = D i , k , k − 1 + D k , j , k − 1 D_{i, j, k}=D_{i, k, k-1}+D_{k, j, k-1} Di,j,k=Di,k,k−1+Dk,j,k−1;
- 若最短路径不经过点k, 则 D i , j , k = D i , j , k − 1 ∘ D_{i, j, k}=D_{i, j, k-1^{\circ}} Di,j,k=Di,j,k−1∘
因此, D i , j , k = min ( D i , j , k − 1 , D i , k , k − 1 + D k , j , k − 1 ) D_{i, j, k}=\min \left(D_{i, j, k-1}, D_{i, k, k-1}+D_{k, j, k-1}\right) Di,j,k=min(Di,j,k−1,Di,k,k−1+Dk,j,k−1) 。
代码
for ( int k = 1; k <= n; k ++) {
for ( int i = 1; i <= n; i ++) {
for ( int j = 1; j <= n; j ++) {
W[i][j] = min(W[i][j], W[i][k] + W[k][j]);
}
}
}