Algorithm 有向加权边图的算法及其权重

Algorithm 有向加权边图的算法及其权重,algorithm,graph,computer-science,graph-algorithm,Algorithm,Graph,Computer Science,Graph Algorithm,我有一个边上有非负权重的有向图 我的算法应该执行以下操作: 获取从顶点u到顶点v的所有路径 计算从u到v的每条路径上的最小加权边 计算我从上面计算的最小加权边的最大值 什么算法适用于此?我问这个问题是因为我可以天真地执行上面所说的步骤(暴力) 我觉得这是对Dijkstra算法的轻微修改,但我不确定。而且,时间复杂度是什么?< p>实际上考虑从U到V的所有路径的任何算法都会花费指数时间,因为存在这样的路径的指数个数——考虑梯子,或者2xN节点的网格——从一端到另一端,在长维度中,你至少有n个独

我有一个边上有非负权重的有向图

我的算法应该执行以下操作:

  • 获取从顶点u到顶点v的所有路径
  • 计算从u到v的每条路径上的最小加权边
  • 计算我从上面计算的最小加权边的最大值
什么算法适用于此?我问这个问题是因为我可以天真地执行上面所说的步骤(暴力)


我觉得这是对Dijkstra算法的轻微修改,但我不确定。而且,时间复杂度是什么?

< p>实际上考虑从U到V的所有路径的任何算法都会花费指数时间,因为存在这样的路径的指数个数——考虑梯子,或者2xN节点的网格——从一端到另一端,在长维度中,你至少有n个独立的选择,所以至少有2^N条可能的路径

我想你可以修改Dijkstra的算法来做到这一点。上有psuedocode。作为第一次修改,更改第6行以将所有初始距离设置为零。我们需要考虑不变量,我们的第一个不变量可以是dist[v]是到v的路径中最小边的最大值,对于目前为止看到的所有路径。与前面一样,我们将prev[v]设置为undefined,并将v添加到Q,Q是包含当前正在考虑的所有节点的队列。作为初始化的最后一部分,我们将dist[source]=无穷大-而不是0。您可以将此视为一种破解,或者是一种定义从v到v的长度为0且没有任何边的路径中的最小边长度的方法

现在我们知道Q包含所有节点,其中最小边的最大值仍在考虑之中,并且所有此类节点的该值只会不断增加。现在,我们从Q中移除最大值为dist[u]的节点u-这是步骤13,将min更改为max。对于u的每个相邻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是使用诸如优先级队列之类的数据结构实现的,这可能意味着该实现必须在dist[u]的旧值下从优先级队列中删除u,然后在dist[u]的新值下重新插入它

正确性是从不变量中得出的,在每次我们都考虑到迄今为止所考虑的每一条路径的最小边的最大值时,当我们从队列中去除V时,我们知道——因为它对于队列中的所有事物都有最大值——我们可以考虑的其他路径都不可能改变这个值。 做这件事所花的时间和Dijkstra一样,也是出于同样的原因。我们在开始时将每个元素输入队列一次,然后从队列中删除每个元素一次。这告诉我们在第14行中执行删除操作的次数


(计算最小加权边的最大值似乎很奇怪-这里有没有有趣的应用程序,或者这是一个让你思考Dijkstra算法的人工练习?

我认为这里不需要Dijkstra。假设我们选择了具有所需最小-最大边的路径。它显然不包括权重较小的边。所以算法是

  • 拾取
    K
    最重的边
  • 使用dfs/bfs检查
    v
    是否可以从
    u
    通过此边缘到达(
    f(K)为true
  • 如果
    K1>K2
    f(K2)为真
    ,那么显然
    f(K1)为真
  • 所以我们可以在
    K

时间复杂度是
O((N+M)log M)
其中
N
-顶点数和
M
-边数

我建议查阅算法教科书(或维基百科)。我非常喜欢这样。按照长度的降序考虑边,并使用union find查看源和目标何时在同一集合/连接的组件内连接,如何?f(K)是什么?还有,我们甚至如何决定选择具有所需最小-最大边的路径?