关于树的直径的一切
观前须知
笔者的博客主页
声明
本文使用 CC BY-NC-SA 4.0 许可。
本文为笔者在 OI 学习中的复习向学习笔记。
部分内容会比较简略。
如有好的习题会不断补充。
知识简介
以下部分详细证明可见 OI Wiki。
定义
树的直径指树上任意两点间距离的最大值。
两次DFS求解
先以任意点为根找到最远点
再以
适用范围:无负权树。
证明:
当
反证法假设存在更长路径,
分类讨论+画图可得矛盾。
代码:
int dis[AwA], ans;
void Dfs(int u, int fa) {
if (dis[u] > dis[ans]) ans = u;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].v;
if (v == fa) continue;
dis[v] = dis[u] + e[i].w;
Dfs(v, u);
}
}
int GetAns() {
dis[1] = 0;
Dfs(1, 0);
dis[ans] = 0;
Dfs(ans, 0);
return dis[ans];
}
树型DP求解
DFS,以当前点为中间点,考虑最长链和次长链,并把最长链继续上传。
代码:
int f[AwA], ans;
void Dfs(int u, int fa) {
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].v;
if (v == fa) continue;
Dfs(v, u);
ans = max(ans, f[u] + f[v] + e[i].w);
f[u] = max(f[u], f[v] + e[i].w);
}
}
性质
树的权非负时,树的直径中点重合。
反证法易证。
习题
YbtOj P1577 数字转换
考虑到变为比自己小的因数和是有唯一性的,
那么可建树,以比自己小的因数和为父节点。
因数和比自己大的和 1 无父节点,则设为根。
那么问题变为在森林上求树的直径的最大值。
对每棵树分别求一遍即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理