某个函数(u,v) : 表示这个函数用到u、v这两个点
d[v] : 当前顶点v的值
w[u,...,v] : u到v一种路径的权值
一、松弛relax(u,v)
解释:这是一种计算起始点走到某个顶点要多远的算法。我们把每个顶点的值用来表示:出发点到该顶点的权值和(走到这要多远)。
实际操作:对任意访问到的一个顶点u,其中一个相邻的顶点v(u可能还有其他相邻顶点)来说:
顶点u的值 + 路(u,v)的权值 = 对应相邻顶点v的一个值(这个走法是新的,但值不一定是最小的)
如果算出来的“对应相邻节点的一个值”比“这个顶点v点目前的值”小,那就把这个值赋给对应相邻顶点v
二、一些性质
三角不等式的性质
对任意一条边(u,v),(s,v)的最短距离小于等于(s,u)的最短距离加(u,v)任意边(感觉没什么用啊)
上界性质
对所有顶点v,d[v] 肯定存在一个最小的数,这个数就是最短路径的权值,d[v]一但在变化中变成这个值就不会再变了。
没路径性质
出发点点u到顶点v没有路径,则v的值是无穷∞
收敛性
w(s,u,v)是图里的一条最短路径,如果d[u]是(s,u)的最短距离,那么Relax(u,v),此时d[v]是(s,v)最短距离
三、单个源点的最短路径
贝尔曼福特算法 Bellman-Ford Alogrithm(路的权可有负值,有向图)
算法思路:从出发点开始,对每条边疯狂地松弛。
- 初始化,对每个定点赋值无穷大∞,复杂度:V上界
- 对图里每一条边,不断松弛,执行 V(顶点的个数)-1 次,复杂度:O(V模E模)
- 对图里的每条边u、v,如果d[v]大于d[u]加w(u,v),说明存在负权回路,表示没有最短路径复杂度:O(E模)
- 如果都行,就实行
狄杰斯特拉算法 Dijkstra Algorithm(路的权必须为正值,有向图)
算法思路:搞一个队列存放未被作为松弛起点的顶点,不断找到里面值最小的顶点进行松弛、出队
- 将其事顶点点赋值0,其他顶点赋值无穷大∞,并将所有顶点加入队列Q,集合S设为空
- 只要Q不为空:找到具有最短路径估计的点u,把u相邻的所有的顶点松弛;把u出队,加入集合S,复杂度O(V模的平方)
这样子算出来,任何一个顶点u的值d[u]都是起始点s到顶点u的最小值
图片来自《算法设计与分析》张德富
仅供个人学习和他人参考之用