图表中所有最短路径(一次更改)

时间:2019-03-03 16:06:26

标签: algorithm

假设我有一个有向图G(V,E),它的边缘上有正整数权重,我需要做的就是找到它的某些节点之间的最小距离,在这个最小距离路径中,我最多可以使用K个反向边缘。 例如,对于此输入:

6(节点)

9个(边缘)

2(正整数K)

10(我需要找到最小距离的边对数量)

2 1 2(2-> 1的边缘,权重2)

3 2 7(3-> 2的边,重量为7)

4 5 6

1 3 8

1 4 4

5 2 8

5 6 10(边缘7)

1 5 5(边缘8)

4 2 5(边缘9)

1 6 1(问题1:使用1个反向边缘找到1-> 6的最小距离)

3 5 0(问题2:使用0个反向边缘找到从3-> 5的最小距离)

1 2 0

3 5 1

1 2 1

4 3 1

6 4 0

2 6 2

6 4 1

6 4 2(问题10)

输入的不同部分可以使用边数(9个,前9行包含3个数字)和所问的问题数(10个,边后的10行)来分隔

输出必须为:

15(问题1的答案:使用1个后沿从1-> 6的最小距离为15)

14

9

13

2

12

不可行(两个边缘之间没有路径,使用0个反向边缘)

17

24

16

我考虑为每个问题和每个边运行Dijkstra,而不是仅仅计算与源的单个最小距离,也要使用反向边并尽可能多地更新值而不会使用超过K个反向边(标签为像(节点号,到源的最小距离,使用了反向边缘)。但是dijkstra找到了从源到所有其他节点的最短路径,我认为这可能对我的实例来说是一个过大的杀伤力。这样可以更有效地做到吗?

1 个答案:

答案 0 :(得分:1)

您可以在每个节点上运行dijkstra,将图视为无向图。您需要跟踪最小距离和使用的反向节点数。例如,让我们将起始节点设为3。

假设我们需要在问题中找到(3 1 0)和(3 1 1)。

我们将节点3初始化为(0,0),并将所有其他节点初始化为(INFINITY,0)。从节点3,我们可以沿直线方向转到节点2,或者沿相反的方向转到节点1。这样我们得到

  

节点1(8,1)和节点2(7,0)

从节点2开始,我们沿直线方向转到节点1。因此我们得到

  

Node1(8,1)(9,0)。这意味着如果反转0个边,则从节点3到节点1的最小值为9,如果反转1个边,则为8。

对于每个节点,您都可以在HashMap中进行跟踪,答案将是0到k之间的最小距离。例如,我们可以得到Node2(7,0)(10,2)。这里的答案是,当允许两个边缘反转时仍为7,如10> 7。

此算法的复杂度为O(n *(n + m))。