单源最短路径

最优子结构——最短路径的子路径也是最短路径,动态规划和贪心算法的一个重要指标。

环路     一条最短路径不可能包含环路     1)    环路权重为负,如果有一条环路权重为负,则不存在最短路径     2)    环路权重为零,如果包含该环路,则将该环路去掉即可     3)    环路权重为正,去掉改环路可以得到更短的路径,因此不可能是最短路径

最短路径的表示     对于每个结点v,维持一个前驱结点v.p,可能是另外一个结点或者NIL

松弛操作     对每个结点,维持一个属性v.d,记录从源结点s到结点v的最短路径权重的上界;称v.d为s到v的
最短路径估计

INITIALIZE-SINGLE-SOURCE(G, s)        
//最短路径估计及前驱结点初始化     for each vertex v 属于 G.V         v.d = INF         v.p = NIL     s.d = 0     
松弛过程【针对一条边(u, v)】:先测试是否可以对s到v的最短路径进行改善,测试的方法为,将从结点s到结点u的最短路径距离加上u与v之间的边权重,并与当前的s到v的最短路径估计进行比较;如果前者更小,则进行v.d和v.p的更新 RELAX(u, v, w)     if v.d > u.d + w(u, v)         v.d = u.d + w(u, v)         v.p = u

Bellman-Ford算法     一般情况下的单源最短路径问题,边的权重可以为负值     返回一个布尔值,以表明是否存在一个从源结点可以到达的权重为负值的环路 BELLMAN-FORD(G, w, s)     INITIALIZE-SINGLE-SOURCE(G, s)                    
//对各个结点的p和d进行初始化     for i = 1 to |G.V| – 1                                          
//每一个点,对每一条边都需要进行松弛操作         for each edge(u, v) 属于 G.E             RELAX(u, v, w)     for each edge(u, v) 属于 G.E         if v.d > u.d + w(u, v)                                    
//如果不存在权重为负值的环路,则二者是相等的             return FALSE     return TRUE

有向无环图中的单源最短路径问题     根据结点的拓扑顺序次序来对带权重的有向无环图G = (V, E)进行边的松弛操作,可以在O(V + E)时间内计算出从单源最短路径问题 DAG-SHORTEST-PATHS(G, w, s)     topologically sort the vertices of G               
//先对点进行拓扑排序,O(V + E)     
INITIALIZE-SINGLE-SOURCE(G, s)
    for each vertex u, taken in topologically sorted order        
//按拓扑排序对结点进行一遍处理
        for each vertex v 属于 G.Adj[u]
            RELAX(u, v, w)


Dijkstra算法
    要求所有变的权重都为非负值
    维持了一组结点集合S,源结点s到这组结点的最短路径已经求出;算法重复从V-S中选择最短路径估计最小的结点u,将u加入到集合S中,然后对所有从u发出的边进行松弛
    使用一个最小优先队列Q保存结点集合S,每个结点的关键字为其d值
DIJKSTRA(G, w, s)
    INITIALIZE-SINGLE-SOURCE(G, s)
    S = 空集
    Q = G.V
    while Q 不等于 空集
        u = EXTRACT-MIN(Q)                        //第一个被提取的点即源结点
        S = S 并上 {u}
        for each vertex v 属于 G.Adj[u]
            RELAX(u, v, w)

点赞