在图中查找第二条最短路径(使用回溯)

时间:2016-06-28 19:18:05

标签: c++ algorithm

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

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

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

更新:我读了这个问题。 Which algorithm can I use to find the next to shortest path in a graph? 我的问题与它不同,因为在这个问题上,我可以使用两次边。我将从节点1转到2一次,然后返回1.这使用边缘1-> 2两次。

2 个答案:

答案 0 :(得分:0)

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

从i = 1到k进行循环,然后每次将路径的第i个边缘的值设置为无穷大。在此之后,运行最短路径算法。并且返回所有k个新的最短路径的最小值。

请注意,每个人都只将一条边设置为无穷大。为什么这样做?因为您将在一条边上获得与原始路径不同的最短路径。

然而,你的问题有点模棱两可,因为第二条最短路径意味着下一条最短路径的成本更高。或者它可能意味着找到两条不同的最短路径。我在答案中假设了后一种情况。

答案 1 :(得分:0)

我认为这可能有效:

维护两个数组: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的第二短路径长度。