Dijkstra算法适用于计算非负边权图的单源的最短路径。
这里我们假设源点为s,已经确定最短路径的点集为S,未确定最短路径的点集为T,D[i]代表i点的实际最短路径长度,dis[i]代表Dijkstra算法运行过程中的当前最短路径长度。
算法流程
1. 将T集中dis值最小的u点移到S集(初始时dis[s]=0其他dis值均为+∞)。
2. 用u的所有出边进行松弛操作:dis[v]=min{dis[v], dis[u]+w(u,v)}。
3. 重复1和2直到T=∅。
很明显将T集中的dis值维护为一个堆可以提高算法速度。
证明
只要证明步骤1时D[u]==dis[u]就行。
需要明确的是S集点的性质就是T集中的点存在与否不影响其最短路径,所以u点只要满足这个性质它其实就行属于S集的。
那么u点能不能找到一条路径长度小于dis[u]的路径到达源点s呢?答案是否定的。
此时u点还在T集中,T集中的任意点v要到达s必然要经过S集(直接一条边到达s也是经过S集),而v经过S集到达s的最短路径长度就是dis[v](步骤2的结果),而u点如果能寻找到一条小于dis[u]的路径D[u]到达s,则必然要经过一条非负长度的路径到达v(从u点直接进入S集那最短路径长度就是dis[u]),然后从v点进入S再到达s的最短路径必然≥dis[u](T集点要到达s必然要经过S集,且dis[v]≥dis[u]),因此有D[u]≥dis[u],然而很明显D[u]≤dis[u],因此D[u]==dis[u]。
3591

被折叠的 条评论
为什么被折叠?



