很久没写blog了,今天水一篇。
今天来讲讲树的直径
树的直径
什么?你不知道什么是树?点此处
什么是树的直径呢?
树的直径就是树中两个节点最远的距离。
那该如何求呢?
其实也很简单。
方法一:树形dp
我们可以运用树形dp,设
表示从节点x出发走向以x为根的自述,能够到达最远节点的距离,若
表示边权,y表示x的子节点,则有:
接着,我们考虑经过节点x的最长链的长度,设为
,则答案为
那么我们想如何转移
,显然
但是这样去枚举的时间复杂度难道不是很不能接受吗?
那我们想一想怎么优化吧~
请大家想一想g数组是怎么弄成的?
在未转移完g数组时,g数组是不是就指的是已做的儿子的max?是吧
那么我们就可以先转移F,再转移g了,具体实现看代码。
void dfs(int u,int fa){
for (int i=head[u];i;i=e[i].next){//链式前向星
int v=e[i].to;
if (v==fa) continue;
dfs(v,u);
ans=max(ans,g[u]+g[v]+e[i].w);//e[i].w指的是边权
g[u]=max(g[u],g[v]+e[i).w;
}
return;
}
方法二:两次BFS/DFS
我们设一棵树的根为root,那么先用DFS/BFS求出离root最远的点p,再从点p开始DFS/BFS,求出最远的q,那么p和q的路径就是树的直径。
因为不是的话,一定能找到更长的链,但与直径定义矛盾
具体证明留给读者。
就不来程序了。
总结
大家应该能看懂!点个赞吧!
对了,我的blog!
若有不当的地方,欢迎大家指出!