用于找到最小化两个节点之间的最大权重的路径的算法

时间:2015-04-27 16:14:50

标签: algorithm graph graph-algorithm shortest-path

我想乘车从X市到Y市。我的车有一个小油箱,加油站只存在于道路交叉口(交叉口是节点,道路是边缘)。因此,我想采取一条路径,使我在两个加油站之间行驶的最大距离最小化。我可以使用什么有效的算法来找到该路径?蛮力是一个坏的解决方案。我想知道是否存在更有效的算法。

1 个答案:

答案 0 :(得分:9)

这是一个简单的解决方案:

  1. 按重量对边缘进行排序。

  2. 开始逐个添加(从最轻到最重),直到XY连接。

  3. 要检查它们是否已连接,您可以使用union-find 数据结构。

  4. 时间复杂度为O(E log E)

    正确性的证明:

    1. 正确答案不大于此解决方案返回的答案。情况就是这样,因为解决方案是建设性的:一旦XY在同一个组件中,我们就可以明确地记下它们之间的路径。它不能包含更重的边缘,因为它们还没有被添加。

    2. 正确答案不小于此解决方案返回的答案。我们假设在XY之间存在一条路径,该路径由权重严格小于返回答案的边组成。但是不可能,因为之前处理了所有较轻的边缘(我们按排序顺序迭代它们)并且XY处于不同的组件中。因此,它们之间没有路径。

    3. 1)和2)暗示该算法的正确性。

      此解决方案适用于无向图。

      这是一个解决定向案例问题的算法(它也适用于无向图):

      1. 让我们根据权重对边缘进行排序。

      2. 让我们对路径中最重边缘的权重进行二分搜索(它由所有边缘的排序列表中的边缘索引确定)。

      3. 对于固定答案候选人i,我们可以执行以下操作:

        1. 在排序列表中添加索引最多为i的所有边(即,所有边都不比当前边重)。

        2. 运行DFS或BFS以检查是否存在从XY的路径。

        3. 根据此类路径的存在,在二分查找中调整左右边框。

      4. 时间复杂度为O((E + V) * log E)(我们运行DFS / BFS log E次,每次都在O(E + V)时间内完成。

        这是一个伪代码:

        if (X == Y)
            return 0 // We don't need any edges.
        if (Y is not reachable from X using all edges)
            return -1 // No solution.
        edges = a list of edges sorted by their weight in increasing order 
        low = -1 // definitely to small(no edges)
        high = edges.length - 1 // definitely big enough(all edges)
        while (high - low > 1) 
            mid = low + (high - low) / 2
            g = empty graph
            for i = 0...mid
                g.add(edges[i])
            if (g.hasPath(X, Y)) // Checks that there is a path using DFS or BFS
                 high = mid
            else
                 low = mid
        return edges[high]