YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

定义状态数组dp[i]表示以i为根节点,可以走的最远距离,也可以理解为以i为根节点树的高度。

我们考虑树的直径,

 

 假设y是直径上的一个端点,X1和x2均为y的儿子节点,我们通过回溯的思想最先求出的应该是dp[x1],此时的dp[y]=0,然后下一步更新直径的长度,maxlen=max(maxlen,dp[y]+dp[x1]+val1)(val表示的是x1和y之间的距离),然后再更新dp[y]=dp[x1]+val1,接着回溯x2的值,dp[x2]被求出,注意在回溯x1的值的时候,dp[y]已经被求出来了即dp[x1]+val1,我们再更新直径的时候maxlen=max(maxlen+dp[y]+dp[x2]+val2),其实就相当于maxlen=max(maxlen,dp[x1]+val1+dp[x2]+val2); 也就是整个弯链的长度。

code:

void dfs(int  x,int pa){
    for(int i=head[x];i;i=edge[i].nxt){
        int  y=edge[i].to;
        if(pa==y) continue ; 
        dfs(y,x);
        maxlen=max(maxlen,dp[x]+dp[y]+edge[i].val);    
        dp[x]=max(dp[x],dp[y]+edge[i].val);
    }
}

注意这里的

        maxlen=max(maxlen,dp[x]+dp[y]+edge[i].val);    
        dp[x]=max(dp[x],dp[y]+edge[i].val);
前后顺序有讲究,防止出现maxlen=dp[x1]+dp[x1]+val这种情况
posted on 2020-08-20 19:58  Target--fly  阅读(176)  评论(0编辑  收藏  举报