[算法模版]树的重心和直径
[算法模版]树的重心和直径
树的重心
定义
以树的重心为根时,所有的子树(不算整个树自身)的大小都不超过整个树大小的一半。
找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心。
删去重心后,生成的多棵树尽可能平衡。
性质
树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么他们的距离和一样。
把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两个树的重心的路径上。
在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
求法
树的重心可以通过简单的两次搜索求出。
- 第一遍搜索求出以每个节点为根的子树中结点数量
- 第二遍搜索找出使 最小的节点 。
实际上这两步操作可以在一次遍历中解决。对节点 u 的每一个儿子 v 递归处理,然后以 更新 的子节点子树节点数最大值,处理完所有子结点后,判断 u 是否为重心。
(代码来自叉姐)
struct CenterTree {
int n;
int ans;
int siz;
int son[maxn];
void dfs(int u, int pa) {
son[u] = 1;
int res = 0;
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].to;
if (v == pa) continue;
dfs(v, u);
son[u] += son[v];
res = max(res, son[v]);
}
res = max(res, n - son[u]);
if (res < siz) {
ans = u;
siz = res;
}
}
int getCenter(int x) {
ans = 0;
siz = INF;
dfs(x, -1);
return ans;
}
}
参考
http://fanhq666.blog.163.com/blog/static/81943426201172472943638/
https://www.cnblogs.com/zinthos/p/3899075.html
树的直径
定义
树的直径指树上的最长简单路径
求法
随意寻找一个点进行,找到的最远点一定为直径的一个端点。再从开始,找到的最远点一定是直径的另一个端点。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决