假设我有一个有向图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找到了从源到所有其他节点的最短路径,我认为这可能对我的实例来说是一个过大的杀伤力。这样可以更有效地做到吗?
答案 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))。