我有一个在边缘有非负权重的有向图。
我的算法应该执行以下操作:
什么算法对此有好处?我问这个是因为我可以天真地去实施上面的步骤,因为我已经说过了(蛮力)。
我觉得这是对Dijkstra算法的一点修改,但我不确定。那么,时间的复杂性是什么?
答案 0 :(得分:1)
我认为我们不需要这里的dijkstra。假设我们选择了具有所需minmax边缘的路径。它显然不包括权重较小的边缘。所以算法是
K
最重的边缘v
是否可以通过此边缘u
<{li}}访问f(K) is true
K1>K2
和f(K2) is true
,那么显然是f(K1) is true
K
时间复杂度为O((N+M) log M)
其中N
- 顶点数和M
- 边数
答案 1 :(得分:0)
任何实际考虑从u到v的所有路径的算法都需要指数时间,因为有一个指数的这样的路径 - 考虑一个梯形图或一个2xN节点的网格 - 从一端或另一端走长维您至少有N个独立选择,因此至少有2 ^ N个可能的路径。
我认为你可以修改Dijkstra的算法来做到这一点。在https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Pseudocode有伪代码。作为第一修改,改变线6以将所有初始距离设置为零。我们需要考虑不变量,我们的第一个不变量可以是dist [v]是到v的路径中最小边缘的最大值,对于到目前为止看到的所有路径。和之前一样,我们将prev [v]设置为undefined并将v添加到Q,该队列包含当前正在考虑的所有节点。作为初始化的最后一部分,我们设置dist [source] = infinity - 而不是0.您可以将其视为一个hack,或者作为一种定义长度为0的路径中从v到v的最小边长的方法没有任何优势。
现在我们已经知道Q包含所有节点,其中仍然在考虑最小边缘的最大值,并且所有这些节点的这个值只会增加。现在我们从Q中删除具有最大值dist [u]的节点u - 这是步骤13修改,最小值变为最大值。对于你的每个邻居v,我们计算min(dist [v],length(u,v))。这是沿着从源到u的任何路径的最大可能最小边长的新候选者,因此如果这大于dist [u],我们将dist [u]设置为该值。注意,这意味着没有Q的元素u将dist [u]设置为大于我们刚删除的Q的元素v的dist [v]的值,这是队列中的最大值那时候。这意味着一旦我们从队列中移除了元素v,其值dist [v]已经计算好,并且不能通过任何后续计算来增加。请注意我们刚刚更改了队列Q中的节点dist [u]。如果Q使用数据结构(如优先级队列)实现,这可能意味着实现必须从旧的优先级队列中删除u dist [u]的值,然后将其重新插入dist [u]的新值。
正确性来自不变量 - 每次我们有dist [v]沿着目前为止所考虑的每条路径的最小边缘的最大值,并且当我们从队列中移除v时我们知道 - 因为它具有一切的最大值仍在队列中 - 我们可以考虑的其他任何路径都不可能改变该值。
这样做的时间与Dijkstra相同,并且出于同样的原因。我们在开始时将每个元素输入队列一次,然后我们从队列中删除一次元素。这告诉我们在第14行执行删除操作的次数。
(最小加权边缘的最大值似乎很难计算 - 这里有一个有趣的应用,或者这是一个让你想到Dijkstra算法的人工练习?)