【轨迹】树的直径 - tree dp,搜索
找树的直径上的点
树DP:可处理负权边 随意选根;记录每个节点前二深度,(DFS形态的)DP到根距离;再 for 一个n 找最大前二深的和作为直径
搜索:随意选起点;DFS/BFS记录距离;记录最远那个/set找出最远的几个,任取一个;再BFS找到最远的多个另一端;for全员找到所有可能直径
:搜索可以找直径端点.
例题1:B. Dynamic Diameter
给定一棵 n 个节点的树和一个自由节点,问将该自由节点依次与前 n 个节点相连时,新的树的直径依次是多少。
一句话题解:关键在于确认原树上哪些节点可以是原树直径的端点。
- 两次 DFS 找到 A、B ,ABC为树的一条直径的两端点
- 因为第一次 DFS 出的是到 0 的距离,第二次出的到 A ,所以需要进行第三次 DFS 来出所有点到 B 的距离,同时又找到了一个点 C(C没用)
一个点 P 若是树的直径的端点,那么 P 要么与 A 组成树的一条直径,要么与 B 组成树的一条直径。
proof: etc.
验证 P 与 B 的距离、与 C 的距离是否等于 BC 的距离(即直径的长度)。若相等,则 P 可以是原树的直径的端点。
记深度然后加那里长很像三角形两边之和大于第三边
例题2:F. Tree Destruction
拆掉一棵 n 个节点的树,每次选择一对节点,贡献为它们的距离,操作为将选中的两个节点中任意一个节点删掉。求最大贡献。
学院派思路:___
我的思路:
首先,拆比较难维护,于是倒过来,变成建树。
然后,既然要建树,就要找建的树的起点,即思考:题目所说的、最后留下来的点,应该是怎样的?应该在 a. 树的中心 b. 树的一个直径的一个端点
接着,我应该怎样加,才能每次操作的贡献都尽可能大呢?
加在直径端点上最好。——但是边是给定的
关于直径端点,我可以 O(n) 找到至少两个。关于长度,我可以 DFS 三次。
以一个端点为根 DFS (plan b.)
然后?既然一个点连的边是定的,就让另一个点尽量远。两个直径端点选一个(例1)。
是否可构造?按照 dfn 序倒着删,就可以一直留着直径的两个端点,最后再删直径即可。
但是!第一次 dfs 不一定找到最深的(换句话说,dfn 序前几的点不一定是直径上的点)——需要维护直径上的点树无环,三角形一下即可
submission (一次过还是很有纪念意义的)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现