我想知道,如果有一个加权图G(V,E),并且我需要找到其中任意两个顶点S和T之间的单个最短路径,那么我可以使用Dijkstras算法。但是当我们需要找到从S到T的所有不同的最短路径时,我不确定如何做到这一点。它是否可以在O(n)时间内解决?我还有一个问题,比如如果我们假设图中边的权重可以假设只在某个范围内的值,那么说1< = w(e)< = 2会影响时间复杂度吗?
答案 0 :(得分:0)
你可以使用Dijkstra来做到这一点。在Dijkstra的算法中,您可以根据距离源的距离为每个节点分配标签,并根据此距离(最小的第一个)结算节点。目标节点确定后,您将拥有最短路径的长度。要检索路径(=边缘序列),您可以跟踪已结算的每个节点的父节点。要检索所有可能的路径,您必须考虑每个节点的多个父级。
一个小例子:
假设您有一个如下图所示(为简单起见,所有边的权重为1):
B
/ \
A C - D
\ /
E
当您使用dijkstra找到距离A-> D时,您将获得3.您将首先使用距离0来定居节点A,然后将距离为1的节点B和E,距离为2的节点C以及最后的节点D距离3.要获得路径,您将在解决它们时记住节点的父节点。在这种情况下,您首先要设置B的父节点和C =节点A.然后,您需要将节点C的父节点设置为B和E,因为它们都提供相同的长度。节点D将节点C作为父节点。
当您需要路径时,您可以按照父指针进行操作,从D开始并在每次节点有多个父节点时进行分支。这将为您提供节点C的分支。
上面评论中提到的帖子使用相同的原则,虽然它不允许您实际提取路径,但它只给您计数。 最后一句话:Dijkstra不是线性时间算法,因为你需要做很多操作来维护你的队列和节点集。
答案 1 :(得分:0)
(a)使用s中的BFS标记通常访问的节点,同时更改以下内容:
(b)对于每个节点v,它有一个记录L(v)代表v所在的层和一个记录f(v) 表示传入路径的数量:
(c)每次在另一个节点的v2邻居中找到节点v1时:
(d)如果v1不在队列中,则将其添加到队列中,L(v1)= L(v2)+ 1,f(v1)+ = f(v2)
(d)如果v1已经在队列中且L(v1)等于L(v2),则什么都不做。
(e)如果v1已经在队列中但L(v1)不等于L(v2),则f(v1)+ = f(v2)
(f)直到在这个模态化的BFS中,第一次从队列中弹出,我们有f(t)
(g)并且该f(t)表示从s到t的不同最短路径的数量
这可能会解决您的问题。