找到无向加权树中的最长路径

时间:2013-01-15 13:31:05

标签: graph-algorithm

我有一棵树,每个边都被赋予一个权重(一个可以是正数或负数的实数)。我需要一种算法来找到最大总重量的简单路径(也就是说,路径中边缘权重之和最大的简单路径)。路径开始或结束的节点没有限制。

我有一个可能的算法,但我不确定它是否有效,我正在寻找证据。这是:

  1. 选择任意节点 u 并运行DFS( u )以查找从 u 开始的最大权重简单路径。让( u v )成为这条道路。
  2. 运行DFS( v )以查找从 v 开始的最大权重简单路径。让这条路径为( v z )。
  3. 然后( v z )是一个最大权重的简单路径。该算法在图的大小上是线性的。任何人都可以告诉我它是否有效,如果有,请提供证据吗?

    注意: Longest Path Problem是带有周期的常规图表的NP-Hard。但是,我只考虑这里的树木。

3 个答案:

答案 0 :(得分:1)

如果允许负权重,请考虑以下示例:

a<->b : -5000
a<->c : 1
b<->d : 1
b<->e : 1

最长路径 d&lt; - &gt; b&lt; - &gt; e 长度为2

随意选择 a 开始。 DFS以距离1返回 c 。第二个DFS返回 a ,距离为1.但是 a&lt; - &gt; c 不是最长的路径。

答案 1 :(得分:0)

这是一个证明它有效的证据。该算法找到一对节点x0,y0,使得max_x d(x,x0)= max_y d(x0,y)(即,x0和y0彼此是最远的节点)。对于任何这样的对,d(x0,y0)是直径。证明:让x *,y *为两个节点s.t. d(x *,y *)是直径。存在节点r和s,使得路径看起来像x0-r-s-y0和x * -r-s-y *。假设d(x0,y0)&lt; d(x *,y *),然后d(x0,y *)&gt; d(x0,y0)或d(y *,x0)> d(y0,x0),与x0和y0是彼此最远点的事实相矛盾。因此d(x0,y0)= d(x *,y *)

答案 2 :(得分:0)

如果您确定图表中没有循环,我会尝试类似:

function findLongestPath(tree)
begin

   all_paths := {}

   for each neighbour 
      all_paths.append(create_path(this_node, findLongestPath(three - current_node))

   sort_descending(all_paths)
   return  all_paths[0];
end

该算法可以进一步优化,只存储最佳路径而不是集合(无需存储所有可能的路径和排序)。