码迷,mamicode.com
首页 > 其他好文 > 详细

树的直径

时间:2020-04-23 23:32:16      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:tail   概念   长度   算法   net   nbsp   情况   eve   证明   

一、概念

  在一棵树中找到距离根节点最远的两个点,这两个点之间的距离为树的直径

二、算法

  1.求法:求树的直径的方法就是在树上任选一点u,求距离点u最远的点y,再求距离点y最远的点s,点y到点s的距离即为树的直径。

  2.证明:假设此树的最长路径是从s到t,我们选择的点为u。反证法:假设搜到的点是v。

    1、v在这条最长路径上,那么dis[u,v]>dis[u,v]+dis[v,s],显然矛盾。
    2、v不在这条最长路径上,我们在最长路径上选择一个点为po,则dis[u,v]>dis[u,po]+dis[po,t],那么有dis[s,v]=dis[s,po]+dis[po,u]+dis[u,v]>dis[s,po]+dis[po,t]=dis[s,t],即dis[s,v]>dis[s,t],矛盾。
    也许你想说u本身就在最长路径,或则其它的一些情况,但其实都能用类似于上面的反证法来证明的。
    综上所述,你两次dfs(bfs)就可以求出最长路径的两个端点和路径长度。
(注:该证明引自原文链接:https://blog.csdn.net/qianguch/java/article/details/78216860)

对于每个节点我们要记录两个值:

f1 [ i ] 表示以 i 为根的子树中,i 到叶子结点距离的最大值

f2 [ i ] 表示以 i 为根的子树中,i 到叶子结点距离的次大值

对于一个节点,它到叶子结点距离的最大值和次大致所经过的路径肯定是不一样的

若j是i的儿子,那么(下面的 w [ i ][ j ] 表示 i 到 j 的路径长度):

若 f1 [ i ] < f1 [ j ] + w [ i ][ j ],f2 [ i ] = f1 [ i ],f1 [ i ] = f1 [ j ] + w [ i ][ j ];
否则,若 f2 [ i ] < f1 [ j ] + w [ i ][ j ],f2 [ i ] = f1 [ j ] + w [ i ][ j ]; 
理解:这样做就是,先看能否更新最大值,若能,它的次大值就是原先的最大值,再更新它的最大值;若不能,就看能不能更新次大值,若能,就更新,不能就不管它

这样的话,最后的答案 answer = max { f1 [ i ] + f2 [ i ] }
引自:https://blog.csdn.net/forever_dreams/java/article/details/81051578

树的直径

标签:tail   概念   长度   算法   net   nbsp   情况   eve   证明   

原文地址:https://www.cnblogs.com/liumengliang/p/12764090.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!