令(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.现在没有从a
到g
的连接,反之亦然,但我们可以让两个人离开{{1分别和a
相遇并在一个共同点上相遇。我们希望找到在一个节点处相遇的两条路径的最短和,以便一条路径从g
开始,另一条路径从a
开始。这个有向图的简单绘图将揭示答案是这两条路径:
g
总距离为4.如何编写接受有向图(如上所述)和两个节点(在本例中为a->c->e
g->f->e
和a
)的算法并输出此答案,我想这可能是g
的形式?我试图让Dijkstra的算法适应,但没有运气。我欢迎所有的想法。
编辑:以上是真实问题的简化版本。这是真正的问题,我不愿意描述,因为一个示例图表太难以阅读。所以我将在没有示例图的情况下对其进行描述。
在类似于上面的有向图中选择两个点A和B但是更大。从一个点到另一个点没有连接,也没有从A和B 可以达到的公共点。但是,我们知道存在点(没有给出多少)N1,N2,...... Nk,这样就可以从A和N1到达一个公共点,一个可以从N1和N2到达的公共点,...可以从Nk和B到达的公共点。我们希望找到这些k + 1路径,使得这些路径的总和最小。这是真正的问题。
答案 0 :(得分:2)
你没有正确地适应Dijkstra。在每种情况下,您不必为每个节点x找到dist(a,x)和dist(g,x)。
在Dijkstra的算法中,每个节点都被视为已访问或未访问,并且搜索将继续进行,直到目的地被访问(或者无法进一步搜索)。
在变体中,每个节点都是Unvisited,Visited-By-A,B by Visited-By-By-Both-Both。当一个节点变为Visited-By-Both时,它的路径之和是对搜索的限制;代码将跟踪找到的最小总和,并在仍在探索的最短路径长于此总和时终止搜索。
我认为在最坏的情况下,此搜索是 O(V logV)。
编辑:“真正的”问题。
我们有A和B,我们正在搜索最小化的{N},{x}
(| A,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 。同样地,必须存在路径在后沿进入并沿着前沿离开的节点;我们标记这些N i 。 (必须至少有一个N,因为x 1 不能是x k ,因为我们假设A和B都没有前向可达的点。)< / p>
如果我们打破全进和全进的路径,我们得到
A - &gt; x 1 ,x 1 &lt; - N 1 ,N 1 - &gt; x 2 ,x 2 &lt; -N 2 ,N 2 - &gt; x 3 ,...,x k &lt; -N k ,N k - &gt;乙
此路径的长度为
| A,X <子> 1 子> | + | N 1 ,x 1 | + | N 1 ,x 2 | + | N 2 ,x 2 | + | N 2 ,x 3 | + ... + | N k ,x k | + | N k ,B |,这对于A,B的选择来说是最小的。
因此,这些是我们正在寻找的路径(它们可以通过图形的简单O(V)变换和Dijkstra搜索(O(VlogV))来找到。