[英]Single-source shortest path in a graph with positive weights and diameter 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]
的值是Arr
中包含node
的双向链表节点,如果没有, null
节点。 当我们找到从起始节点到相关节点的长度为i
的路径时,我们将一个节点存储在列表Arr[i]
中。
将一个节点添加到尚不存在的优先级队列需要O(1)
- 如果我们有一个暂定距离s
,那么我们将该节点添加到链表Arr[s]
并相应地更新location[node]
。 请注意,如果优先级为>D
,我们实际上应该避免将节点完全添加到优先级队列中,并确信我们稍后会将其添加到优先级<= D
的队列中。
从优先级队列中删除给定节点也是O(1)
- 我们可以使用location[node]
在O(1)
中找到它的双向链表节点,从双向链表中删除该节点,然后设置location[node]
到null
。 当我们更改节点的优先级时,我们将需要此操作。
查找和删除最小节点并不那么简单。 我们不断增加i
直到我们找到一些i
使得Arr[i]
不为空。 然后我们从优先级队列中删除在Arr[i]
中找到的节点(不要忘记更新location[node]
)。 整个程序中完成的增量总数为D
,因为我们将i
从0
更改为D
一次增量。 忽略增量,此过程中完成的其他工作是O(1)
。
请注意,这仅是有效的,因为我们可以保证,一旦我们删除了优先级为i
的节点,我们将永远不会将另一个优先级<i
的节点添加到优先级队列中。 它也只是有效的,因为我们知道我们永远无法真正删除添加到优先级队列中优先级> D
的任何东西,因为我们只能在优先级队列具有最终确定的正确路径长度时从优先级队列中删除一些东西,即<= D
- 因此,没有必要向优先级队列中添加任何优先级> D
的内容。 这是根据 Dijkstra 算法的一般属性(当图具有正边权重时)以及图的直径为D
的事实得出的。
因此,根据需要,算法将是O(V + E + D)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.