在图中寻找第二个最短路径(带回溯)

Finding second shortest path in a graph(With Backtracking)

本文关键字:回溯 最短路径 第二个 寻找      更新时间:2023-10-16

我在LightOJ中发现了一个问题,问题是找到从节点1到节点n的图中的第二条最短路径(图中有n个节点标记为从1到n)。现在,问题表明我可以回溯找到第二条最短路径。其中一个示例是这样的:

  • 从节点1到节点2的边缘,花费100。
  • 从节点2到节点3的边缘,花费300。
  • 从节点1到节点3的边缘,成本为50。

这个测试的答案是150,对于路径1->2->1->3。我知道Dijkstra算法。但我找不到任何关于如何做到这一点的资料。我很抱歉,如果这是一个老话题,但我当我谷歌它我找不到任何东西。

更新:我读了这个问题。我可以用哪种算法来找到图中的下一个最短路径?我的问题和它不一样因为在这个问题中,我可以用两条边。我从节点1到节点2走一次,然后回到节点1。这使用边1->2两次。

我想这可能行得通:

维护两个数组:shortest[i]sec_shortest[i],分别表示顶点i的最短路径长度和第二最短路径长度。

现在,您所需要的就是以稍微不同的方式修改Dijkstra算法的update部分中的方法:

for v in adj(u):
    if shortest[u] + cost(u, v) < shortest[v]:
        sec_shortest[v] = shortest[v]
        shortest[v] = shortest[u] + cost(u, v)
    else if shortest[u] + cost(u, v) < sec_shortest[v]:
            sec_shortest[v] = shortest[u] + cost(u, v)

最后,sec_shortest[i]将包含从固定源到顶点i的第二最短路径长度。

我认为有一个更好的解决方案。首先找到最短路径。假设这条最短路径有k条边。

有一个从i = 1到k的循环,然后每次设置路径的第i条边的值为无穷大。之后,运行最短路径算法。然后返回k条最短路径的最小值

注意,每次你只设置一条边为无穷大。为什么会这样呢?因为你会得到一条最短路径它在一条边与原路径不同。

然而,你的问题有点模棱两可,因为第二条最短路径意味着下一条最短路径具有严格更高的成本。也可以是找到两条不同的最短路径。