整理来源:zzu信息工程学院数据结构ppt
本节仅整理最短路径的概念知识。
1 定义
最短路径问题:从图中某一顶点到达另一顶点的路径可能不止一条,求其中一条路径使得沿此路径上各弧上的权值总和最小。称路径的第一个顶点为源点,最后一个顶点为终点。
2类最短路径问题:
- 从某一源点到其余各顶点的最短路径(Dijkstra算法)
- 每一对顶点之间的最短路径(Floyd算法)
注意:考虑到交通图的有向性,我们讨论带权有向图上的最短路径问题
2 源点固定的最短路径问题
2.1 Dijkstra算法
迪杰斯特拉提出了一个按路径长度递增次序产生最短路径的算法,称为迪杰斯特拉算法。
一般情况下,假设S
为已求得最短路径终点的集合,可以证明:下一条最短路径(设其终点为vk
)可能是:
- 弧
<v0,vk>
- 或:中间只经过
S
中的顶点到达顶点vk
的路径。(可以用反证法来证明)
2.2 举例
首先:
经过判断,(v0, v1)是最短的。因此将v1加入到S
中。
然后看i = 2
时的情况:
当i = 2
时,根据Dijkstra算法,可以发现(v0,v1,v2) < (v0, v2),所以更新路径。v3同理。
此时vj = v2, v2进入S
中。
最后看i = 3
的情况:
最终结果:
这里只掌握算法思想,实现方法之后会补上。
3 每一对顶点间的最短路径
3.1 Floyd算法
那么,当我们得到<vi, vj>后,应该做的处理工作如下:
上面这段话看起来麻烦,说白了就是一个一个点的试探过程,从vi到vj之间1每次加一个点进去,观察是否能得到更短的路径。所有的点都试探完了之后就得到了最短路径。
注:“从vi到vj之间”:第一次是(vi,vj),之后可能有更短路径(vi, … , vj)
其实就是这一段代码:(用邻接矩阵存储)
// Floyd算法
for(k = 1; k <= n; k ++)
for(i = 1; i <= n; i ++)
for(j = 1; j <= n; j ++){
if(d[i][k] + d[k][j] < d[i][j]){
d[i][j] = d[i][k] + d[k][j];
path[i][j] = path[i][k];
}
}
3.2 举例
懒得找更多的例子了,O(n3)的时间复杂度人做起来也挺麻烦的……掌握思想就好,代码后续会补充。