若干路径的最短和

Shortest sum of several paths

本文关键字:路径      更新时间:2023-10-16

(x,p1,p2,...pn)表示存在从x到p1的有向边(但不存在从p1到x的有向边),x到p2的有向边,等等…还有一条从x到pn的有向边。假设我们有:

(a,b,c)
(b,d,c)
(c,d,e)
(f,e,h)
(g,f,h,i)
(i,j)

为简单起见,我们假设所有连接节点之间的距离为1。现在从ag没有联系,反之亦然,但我们可以让两个人分别从ag出发,在一个共同的点相遇。我们想要找到两条路径的最短和,这两条路径在一个节点相遇,使得一条路径从a开始,另一条路径从g开始。简单画一下这个有向图就会发现答案是这两条路径:

a->c->e
g->f->e

,总距离为4。如何编写一个算法,接受一个有向图(如上所述)和两个节点(如ag在这种情况下),并输出这个答案,我想可以在形式std::make_pair({a,c,e}, {g,f,e}) ?我试着调整Dijkstra的算法来做到这一点,但没有运气。我欢迎所有的想法。

Edit:以上是实际问题的简化版本。这里是真正的问题,我不愿意描述它,因为示例图太难以阅读。因此,我将不使用示例图来描述它。

在一个类似于上面的有向图中选择两个点A和B,但更大。从一个点到另一个点没有连接,并且也没有从a和B可到达的公共点。然而,我们确实知道存在点N1, N2,…Nk使得a和N1都有一个可达的公点,N1和N2都有一个可达的公点,…我们想要找到这k+1条路径,使得这些路径的总和最小。

您没有正确地适应Dijkstra。你不需要在每种情况下为每个节点x找到dist(a,x)和dist(g,x)

在Dijkstra的算法中,每个节点都被认为是已访问的或未访问的,并且继续搜索直到目的地被访问(或不可能进一步搜索)。

在变体中,每个节点都是未访问的、被a访问过的、被b访问过的或被两者访问过的。当一个节点成为双向访问时,到达该节点的路径之和是搜索的限制;代码将跟踪找到的最小和,并在仍在探索的最短路径大于该和时终止搜索。

我相信这个搜索在最坏的情况下是O(V logV)

编辑: "真正的"问题。

我们有A和B,我们正在搜索使

最小的{N}, {x}

(| x <子> 1 | + | N <子> 1,x <子> 1 |)+ (| N <子> 1,x <子> 2 | + | N <子> 2 ,x <子> 2 |)+ (| N <子> 2 ,x <子> 3 | + | N <子> 3 ,x <子> 3 |)+…+ (| N <子> k ,x <子> k | + | N <子> k ,B |)

其中|x,y|为x到y的最短路径长度。

现在考虑一个新的图,通过向G中添加反向边来生成:对于G中的每条边x->y,我们添加y->x(具有相同的权值,但对于我们的目的,所有权值都是1),但是我们不添加通向a的反向边,然后我们从b中删除正向边。现在在这个新图中找到从a到b的最短路径

这条路径从a开始有一条向前的边,到B结束有一条向后的边,是最短的路径。在路径上,必须有路径沿前沿进入,沿后沿离开的节点;我们标记这些x<下标>i。同样,也必须存在路径从后沿进入并沿前沿离开的节点;我们把这些标记为Ni。(必须至少有一个N,因为x1不可能是xk,因为我们假设A和b都没有前向可达的点)

如果我们把路径分成全向前和全向后的腿,我们得到

> x <子> 1,x <子> 1 & lt;——N <子> 1,N <子> 1 > x <子> 2 x <子> 2 & lt;——N <子> 2 ,N <子> 2 > x <子> 3 ,…, x <子> k & lt;——N <子> k ,N <子> k ——> B

该路径的长度为

|一个x <子> 1 | + | N <子> 1,x <子> 1 | + | N <子> 1,x <子> 2 | + | N <子> 2 ,x <子> 2 | + | N <子> 2 ,x <子> 3 | +……+ |Nk,xk| + |Nk,B|,这是A,B的最小值。

因此,这些是我们正在寻找的路径(它们可以通过图的简单O(V)变换和Dijkstra搜索(O(VlogV))找到)。