若干路径的最短和
Shortest sum of several paths
设(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
没有联系,反之亦然,但我们可以让两个人分别从a
和g
出发,在一个共同的点相遇。我们想要找到两条路径的最短和,这两条路径在一个节点相遇,使得一条路径从a
开始,另一条路径从g
开始。简单画一下这个有向图就会发现答案是这两条路径:
a->c->e
g->f->e
,总距离为4。如何编写一个算法,接受一个有向图(如上所述)和两个节点(如a
和g
在这种情况下),并输出这个答案,我想可以在形式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))找到)。
- 如何将更多文件夹添加到c++include路径
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- C++A*算法并不总是在路径中具有目标节点
- 从函数角度看ID到文件路径的内部与外部映射
- boost xml parsingl将xml的路径作为变量发送
- 对于MacOS上的G++,如何添加默认的include目录/usr/local/include和默认的库搜索路径/usr
- 如何使用cppcheck处理半相对包含路径
- 在C++中设置基于操作系统的文件路径
- 基于编译器选项的编译二进制路径
- 按边长度递归搜索图中所有可行路径
- 使用变量值作为 PlaySound 中的路径
- 如何转换真实路径 CString c++
- 从 GUID 获取 USB 卷路径
- 查找 GCD:并非所有控制路径都返回值
- C++17 文件系统::remove_all 带有通配符路径
- 在带有尾部斜杠的路径上返回 std::filesystem::create_directories() 的值
- 获取当前正在运行的 exe 名称(不是路径)
- 如何从 Skia 路径几何体中获取网格?
- CMake 错误"源似乎不包含 CMakeLists.txt",路径/库连接问题
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)