HDU2196 Computer (树形dp或树的直径)

题意

给定一个n个点的树,两点之间的距离定义为他们两点之间最短路经过的边数,问对于每个i,其它点距离i最远是多少(n小于等于100000)

题解

首先将这棵树转换为有根树
方法一:(利用树的直径)
求出这棵树的任意一条直径(u,v),然后dfs出u及v到其他任意一个点i的距离,那么对于每一个点,最长的距离是 max{dist(u,i),dist(v,i)} ,为什么是这样的,我们考虑反证法。
这里写图片描述
假设此时k到v的距离大于k到u的距离,那么现在与t最远的点一定是v没有比v还远(注意是还远,因为有可能有两条直径)如果说此时那条只有一个端点的边权比(k,v)的边权还大,那么此时直径就不是(u,v),而是(u,一个没有画出的点)
方法二:
设fi表示以i为根的子树中,与i最远的距离。
gi表示以i为根的子树外,与i最远的距离
并假设i的父亲为k
fi的转移就比较显然
fi=min{fj}jsoni
gi的转移需要分类讨论一下
fk的最长路经过i,意思就是说k的子树中到k最远的这个点的路径上有i
看下图:
这里写图片描述
那么此时gi的转移方程为
gi=dist(i,k)+max{gk,second(fk)} 为什么呢,因为gi的定义是除以i为根的子树外,距离i最远的距离。当然不能选他本身。
若此时fk的最长路不经过i那么
这里写图片描述
我们可以从fk,gk中选个大的即可。
gi=dist(i,k)+max{gk,fk}

猜你喜欢

转载自blog.csdn.net/ganjingxian/article/details/78691471