摘要:
1,Floyd算法的介绍和实现步骤
2,Floyd算法的代码实现和优化
3,Floyd算法最短路径打印
4,Floyd算法为什么要先遍历中间顶点 k
1,Floyd算法的介绍和实现步骤
在前面我们讲过迪杰斯特拉算法,Bellman-Ford算法以及SPFA算法,这些都是求单源点最短路径,也就是从计算从一个点到其他所有点的最短路径。而弗洛伊德(Floyd-Warshall)算法是求多源点最短路径的,就是求任意两个顶点之间的最短距离,可以有负权边都不能有负权回路。
我们来思考这样一个问题,如果知道 A 到 B 的距离是 x ,这个 x 可能是一个确定的值,也可能是无穷大,怎么才能使 x 的值变小呢?
唯一的解决方式就是找一个中转点 C ,判断 A 到 C 的距离加上 C 到 B 的距离是否小于 A 到 B 的距离,如果小于,就更新 A 到 B 的值,如果不小于, A 到 B 的值就不变。
如下图所示,A 到 B 的直线距离是 9 ,如果经过顶点 C 中转,距离就会变成 7 。
只需要把所有的点都作为中转点枚举一遍即可,很明显这是一道动态规划的问题,我们定义 dp[k][i][j] 表示经过前 k 个顶点从 i 到 j 的最短距离。
1,如果不经过第 k 个顶点中转,那么:
dp[k][i][j]=dp[k-1][i][j]。
2,如果经过第 k 个顶点中转,那么:
dp[k][i][j]=dp[k-1][i][k]+dp[k-1][k][j]。
只需要取他们的最小值即可,也就是:
dp[k][i][j] = min(dp[k - 1][i][j], dp[k - 1][i][k] + dp[k - 1][k][j]);
我们来画个图看下: