验证无向树中最长路径的不同方法

时间:2014-12-12 07:53:40

标签: algorithm path tree

我正在尝试这个问题 - 找到未加权的无向树中最长的路径。

方法1

Perform BFS from any node(say X) to the farthest possible node(say Y).
*   Then, perform BFS again from Y to its farthest node(say Z).
*   Y-Z is the required length.
*   For keeping track of length we can either keep a flag in the queue
*   or keep a predecessor array which can be updated for every node that we insert
*   in the queue.

简明直观的解释 - 我们开始的节点X总是试图到达作为最长路径(例如YZ)的一部分的节点。因此,越过最长的路径(例如在节点N处)。从那时起,它将有两个选择 - 要么走在最长路径的一个(新西兰)一侧,要么走另一个(纽约州)。它需要更长的纽约和YZ。因此,我们最终会到达最长路径的一端(节点Y)。现在,如果X采取的路径不是与最长路径(YZ)重叠的路径(最大值(纽约,新西兰)),那么,这将意味着存在比最长路径(YZ)更长的路径。

矛盾证明 -

案例1 - 让我们假设是否有一些路径XT与YZ不重叠且长于XN + max(NY,NZ)。 假设S是N和T的最低共同祖先。现在,让长度(UV)成为一个函数,它告诉两个节点u和v之间的路径长度。

We know, Length(XT) = Length(XS) + Length(ST)                 ..... 1
         Length(XY) = Length(XS) + Length(SN) + Length(NY)    ..... 2     
         Length(XZ) = Length(XS) + Length(SN) + Length(NZ)    ..... 3

不要失去一般性,让我们假设,Length(NY)>Length(NZ) ... 4 现在,我们宣称Length(XT) > Length(XY). 因此,使用1,2和4,  我们得到,Length(ST) > Length(SN) + Length(NY).  但是,在那种情况下,在最长路径YZ中,如果我们用NT替换NY,即NS + ST,我们将获得比YZ更长的路径。然后YZ不会是最长的路。因此,这是一个矛盾!

因此证明XN + max(NY,NZ)是从X开始的最长路径,并将我们带到Y,这被证明是绝对最长路径的一端。

同样,我们可以证明情况2 - 当XT与YZ部分重叠时。它留给读者练习。

方法2 (尚未验证为正确)

我的解决方案以及akul建议的更正http://codeforces.com/blog/entry/2845#comment-200512

(我可能已经阅读了这个或类似的长时间回来,但无法关联/回忆) -

*   START -
*   Store all the nodes with their degrees.
*   1. Make a list of nodes of the Tree storing the "Degree" of each node along with the neighbors of the node. 
*
*   2.Initialize length=0;
*
*   3. While there are edges present in the tree, perform the following
*      a. remove the edges connecting all the nodes having degree 1. 
*
*      b.   if(number of edges removed >=2 ) length+=2;
*           else length+=1
*
*      c. update degree of node and its neighbors and the edge information
*
*   return length
*   END.

所以,在这里,我基本上正在做的是缩小最长的路径, 从所有边界(度1)节点开始,作为最长路径 是连接两个1度节点(最远的节点)的节点。

我的问题 - 这种方法(方法2)是否有效?

1 个答案:

答案 0 :(得分:1)

我同意@j_random_hacker这种方法是有效的,并且可以通过矛盾来证明:

证明两个末端节点必须具有1级

  • 假设存在具有度N的末端节点A,其中N> 1
  • 请注意,路径必须包含进入A
  • 的N条边之一
  • 请注意,通过其他边缘之一退出A会扩展路径
  • 因此A不能是终端节点

证明具有1级(除了两个末端节点)的节点不能成为路径的一部分

  • 假设存在程度为1的节点B是路径的一部分,而不是终端节点
  • 请注意,路径必须使用唯一边缘输入B
  • 请注意,退出B
  • 没有剩余边缘
  • 因此B不能成为路径的一部分

但是,我会以稍微不同的方式表达算法。第一次阅读步骤3b,我感到困惑的是else子句需要将长度增加1.经过进一步审查,我终于发现只需要else子句算法结束。最后一次通过步骤3a将留下具有一个或两个剩余节点的图。

如果两个节点保留在末尾,则图形由两个1度节点和一个边缘组成。通过该图的最长路径长度为1.因此,这是一种特殊情况,其中删除两个端节点仅删除一条边。因此,我会重写算法,如下所示,以明确特殊情况只发生在最后。

START
1. Make a list of nodes of the Tree storing the "Degree" of each node 
   along with a list of neighbors of the node. 

2. Initialize length=0

3. While the number of remaining nodes > 2
     a. remove all nodes having degree 1, and remove the corresponding edges  
     b. length+=2
     c. update the degree and the neighbor list of any remaining nodes 

4. if ( number of remaining nodes == 2 )
     length+=1

return length 
END