HDU 2196——Computer【树形DP】

该博客介绍了一种使用树形动态规划方法解决计算树中每个节点到最远节点距离的问题。通过将无根树转化为有根树,利用两次DFS遍历更新节点的状态,得到每个节点的最大和次大距离。最后,给出了AC代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目传送门


Problem Description

A school bought the first computer some time ago(so this computer’s id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.

Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.


Input

Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.


Output

For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).


Sample Input

5
1 1
2 1
3 1
1 1


Sample Output

3
2
3
4
4


题意:

给出一棵树,求离每个节点最远的点的距离


题解:

  • 思路:把无根树转化成有根树分析,
    在这里插入图片描述
    对于上面那棵树,要求距结点2的最长距离,那么,就需要知道以2为顶点的子树(蓝色圈起的部分,我们叫它Tree(2)),距顶点2的最远距离L1
    还有知道2的父节点1为根节点的树Tree(1)-Tree(2)部分(即红色圈起部分),距离结点1的最长距离+dist(1,2) = L2,那么最终距离结点2最远的距离就是max{L1,L2}

  • f[i][0],表示顶点为i的子树的,距顶点i的最长距离
    f[i][1],表示Tree(i的父节点)-Tree(i)的最长距离+i跟i的父节点距离

  • 要求所有的f[i][0]很简单,只要先做一次dfs求每个结点到叶子结点的最长距离即可。
    然后要求f[i][1], 可以从父节点递推到子节点,
    假设节点u有n个子节点,分别是v1,v2…vn
    那么
    如果vi不是u最长距离经过的节点,f[vi][1] = dist(vi,u)+max(f[u][0], f[u][1])
    如果vi是u最长距离经过的节点,那么不能选择f[u][0],因为这保存的就是最长距离,要选择Tree(u)第二大距离secondDist,
    可得 f[vi][1] = dist(vi, u) + max(secondDist, f[u][1])

  • 跟思路中不太相同的是,我们如下设置DP数组:
    dp[i][0] : 表示以i为根的子树中的结点与i的最大距离
    dp[i][1] : 表示以i为根的子树中的结点与u的次大距离(即上述思路中的secondDist)
    dp[i][2] : 表示i往父亲节点方向走的最大距离

同样的,我们也做两次DFS,但是第一次的时候,我们将dp[i][0]和dp[i][1]一起算出来;

第二次DFS就可以直接用dp[i][0]和dp[i][1]。


AC-Code:

#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值