CF911F Tree Destruction
题意:
给你一棵
个结点组成的树,你需要对树进行 次操作,一次操作包含如下的步骤:
- 选择两个叶子结点
- 将这两个结点之间简单路径的长度加到答案中
- 从树上删去两个叶子结点之一
初始答案为,显然在 次操作之后树上只剩下一个结点。
计算最大的答案,并构造一组操作序列。
思路:
构造题……向来是我不拿手的。
浅析一下本人的思考过程。一开始想的是根据结点的深度进行构造,统计出每个深度的结点个数,然后枚举最大和次大的两个深度组合出最长的路径,优先割掉个数较少的深度的点。似乎可以统计出答案,但问题在于你并不知道其中的某两个结点是不是在同一棵子树内,也就不能通过直接计算深度来求两点距离。如果加lca,时间复杂度又炸了。。。
那换一个思路,在一棵树上,且是一条距离最大的路径,似乎与树的直径有关系?
先回顾一下树的直径的一些性质:
- 对任一一个点来说,与它距离最远的点一定是树的直径的某个端点。
- 对于两棵树,如果第一棵树的直径的两端点为
,第二棵树的直径的两端点为 ,那么将两棵树连起来,新树的直径的两个端点一定是四个点中的其中两个点。 - 对于一棵树,增删一个叶子结点,最多改变直径的一个端点。
- 如果一棵树有多条直径,那么所有直径必交于一点。
- 任一两条直径一定有且仅有一个极长连续段重合。
对于这道题来说,第一个性质是最重要的。它为方案的构造指明了思路。
可以先两遍
对于在直径上的点,等把所有不在直径上的点全部删除后,再挨个删掉即可。
这里有个细节,当你在处理没在直径上的点,求哪个端点与与它最远时,还要记录一下这个没在直径上的点和另一个端点的lca,这样才能求距离。算是一个比较有用的技巧吧,在代码里会展示。
__EOF__

本文作者:Never Gonna Give You Up!
本文链接:https://www.cnblogs.com/CZ-9/p/17367748.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/CZ-9/p/17367748.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具