该算法可以解决最短路径问题,原理如下
先由特殊到一般,举个例子
求由节点1到节点6的最短距离
列举每一对直接相连的点的距离
dis | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 0 | 2 | 1 | INF | 6 | 8 |
2 | 0 | INF | INF | 3 | INF | |
3 | 0 | 2 | 3 | INF | ||
4 | 0 | 3 | INF | |||
5 | 0 | 2 | ||||
6 | 0 |
(无向图延对角线轴对称补全表格即可,这里的INF仅表示两点不直接相连)
很明显1到6有一条直接相连的路径,距离为8,如何使之更短?自然是寻找一个点充当1和6连接的桥梁
比如从1先到5再到6.
由此,我们可以枚举每一个可以充当i与j之间的中间结点的点k,判断dis(i,k)+dis(k,j)与dis(i,j)的大小
ps:dis(i,j)表示i到j的距离
实际写的时候,并非先确定i与j,而是确定一个k,枚举每一对i与j
以k=5为例:5可以充当(1和3),(1和6),(3,4)三对点的桥梁,
先看(1,3)这对,dis(1,3)==1,dis(1,5)+dis(5,3)==9,自然是不更新
dis(1,6)==8,dis(1,5)+dis(5,6)==8,不更新
同理dis(3,4)不更新
dis | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 0 | 2 | 1 | INF | 6 | 8 |
2 | 0 | INF | INF | 3 | INF | |
3 | 0 | 2 | 3 | INF | ||
4 | 0 | 3 | INF | |||
5 | 0 | 2 | ||||
6 | 0 |
k=2,有(1,5)一组,dis(1,5)==6,dis(1,2)+dis(2,5)==5,更新
dis | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 0 | 2 | 1 | INF | 5 | 8 |
2 | 0 | INF | INF | 3 | INF | |
3 | 0 | 2 | 3 | INF | ||
4 | 0 | 3 | INF | |||
5 | 0 | 2 | ||||
6 | 0 |
k=1;k<=6;k++枚举即可
核心代码:
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
其实用Floyd每两点之间最短路径都会更新,如果只求一组点效率不高,更适用于多组