当边上有权重时,找到树中最长的路径

时间:2011-03-07 20:22:07

标签: algorithm tree

我正在寻找一种有效的算法。我也很感激对它的清晰分析。

4 个答案:

答案 0 :(得分:2)

答案与上周出现在SO上的this question密切相关。

,而不是寻找数组的子部分,而是想要找到树的子部分。

我认为从最左端节点开始并沿树向上和向下遍历最右端节点跟踪最大路径和和当前路径总和应该足够了。同样,链接问题中的解决方案会跟踪数组中的总和。

答案 1 :(得分:0)

如果不处理任何细节,可以使用简单的DFS搜索

dfs( node, score ):
    max = 0; maxv = None
    for each edge in node
         [val,path]  = dfs( edge.child, edge.cost )
         if(val>max)
             max = val; maxv = path + [node]
    return [max,maxv]

编辑 - 由于此处似乎存在一些混淆,请让我进一步解释。我们可以讨论两个不同的问题,第一个是我们认为这个树被解释为具有单个根的DAG,并且路径从根开始并从该根获取单个路径。在这种情况下,该函数被称为dfs( root, 0 )。在这种情况下,基本上为每个节点选择

建立最大成本
  • A)将其中一个节点作为路径或
  • B)不采取任何路径,因为所有路径都会导致负效用

第二个问题是树不是DAG(由Vlad提出)在这种情况下,我们可以从任何节点开始并在任何节点结束。由于树中没有循环,我们可以运行像Floyd-Warshall这样的算法来找到所有对中最长的路径。

Floyd-Warshall大致相当于上述例程的memoziation。如果我们添加一个额外的参数来跟踪起始节点,并尝试每个起始节点,将重用路径。可能有更好的方法来利用树的结构,我会考虑这个。


Vlad提出的示例(参见回复评论)

             *
          1 / \ 1
           *   *
        -1/
         *

答案 2 :(得分:0)

Dijkstra's algorithm对于这种情况非常有用。

答案 3 :(得分:0)

我认为BFS可能是解决这个问题的正确方法bcoz没有一个分支路径会有一个公共节点(这很明显,因为它是一棵树)。

IDEA:在每个步骤返回BFS期间,我们可以返回从分支节点到子节点的最大长度。但是对于BFS的第一次调用,即对于根节点,我们需要收集最大和最大路径长度,将它们相加,这是答案所需的最大距离。如果根节点上没有多个分支,则最大距离来自根节点。

上述算法的代码:

int BFS(vertex V){

    max_dist_to_children = INT_MIN;

    // Here by parent i refer to the previous vertex
    // through which V is explored (There will be only one parent, think!!)
    for v in (neighbor(V) and v!=V.parent){
        v.parent = V;
        dist = BFS(v);

        if dist > max_dist_to_children:
           max_dist_to_children = dist;
     }

     return dist;
}

从根节点第一次调用BFS与上面的有点不同,因为第一次调用必须返回总和(max_distance,second_max_distance)。