具有正权重和直径 D 的图中单源最短路径

问题描述

一个问题中,我得到一个图 G,它只有 正权重 和它的 直径(即 G 中每对顶点之间的最大最短路径) = D. 该问题要求单源最短路径算法,该算法比 Dijkstra 更快,并在 O(V+E+D) 时间内运行。

到目前为止我所考虑的: 曾经想过添加哑节点的方法,将G转化为未加权的图G',然后运行BFS,但是这样会导致复杂度为:O(V+WE)

(如在 G' 中,E' = O(WE) 和 V = O(WE+V))

在我看来,D 并没有真正帮助降低问题的复杂性,因为权重的总和(即要添加的虚拟节点的总数)与 D 无关。

解决方法

将 Djikstra 算法与优先队列的优化版本一起使用。假设图有节点 0..V-1

优先级队列将由节点的双向链表的数组 Arr[0..D](索引介于 0 和 D 之间的数组)组成,以及索引 i 表示数组中所有节点的优先级与起始节点的距离至少为i,并且是一个数组location[0..V - 1],其中location[node]的值为{中的双向链表节点{1}} 包含 Arr,如果没有这样的节点,则为 node。当我们找到从起始节点到相关节点的长度为 null 的路径时,我们将一个节点存储在列表 Arr[i] 中。

将一个不存在的节点加入优先级队列是i - 如果我们有一个暂定距离O(1),那么我们将该节点加入链表s并更新Arr[s] 相应地。请注意,如果优先级为 location[node],我们实际上应该避免将节点完全添加到优先级队列中,并确信我们稍后会将其添加到优先级为 >D 的队列中。

从优先队列中删除给定节点也是<= D - 我们可以使用O(1)O(1)中找到它的双链表节点,从双链表中删除该节点-list,并将 location[node] 设置为 location[node]。当我们改变一个节点的优先级时,我们将需要这个操作。

查找和删除最小节点不那么简单。我们不断地增加 null 直到我们找到一些 i 使得 i 不为空。然后我们从优先级队列中删除在 Arr[i] 中找到的节点(不要忘记更新 Arr[i])。在整个程序中完成的增量总数为 location[node],因为我们将一次将 Di 更改为 0。忽略增量,此过程中完成的其他工作是D

请注意,这仅是有效的,因为我们可以保证,一旦删除优先级为 O(1) 的节点,我们将永远不会将另一个优先级为 i 的节点添加到优先级队列中。这也只是因为我们知道我们永远无法真正删除添加到具有优先级 <i 的优先级队列中的任何内容,因为我们只能在其最终确定的正确路径长度为 {{} 时从优先级队列中删除某些内容1}} - 因此,没有必要将任何内容添加到优先级为 > D 的优先级队列中。这是根据 Dijkstra 算法在图具有正边权重时的一般性质以及图的直径为 <= D 的事实得出的。

因此算法将是 > D,根据需要。