在线性时间内找出无向加权图中2个节点之间不同最短路径的总数?

时间:2012-10-27 16:57:29

标签: graph distinct shortest-path dijkstra bellman-ford

我想知道,如果有一个加权图G(V,E),并且我需要找到其中任意两个顶点S和T之间的单个最短路径,那么我可以使用Dijkstras算法。但是当我们需要找到从S到T的所有不同的最短路径时,我不确定如何做到这一点。它是否可以在O(n)时间内解决?我还有一个问题,比如如果我们假设图中边的权重可以假设只在某个范围内的值,那么说1< = w(e)< = 2会影响时间复杂度吗?

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的不同最短路径的数量

这可能会解决您的问题。