news 2026/6/10 2:18:53

20251122树的直径、重心、中心

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
20251122树的直径、重心、中心

引入

树是一种特殊的图,因其看起来像一颗倒挂的树而得名。
树的定义为:n nn个点n − 1 n-1n1条边的无向连通图。

树的直径

定义树上任意两点之间最长的简单路径为树的直径,一棵树可能有很多直径,如菊花图等。

DFS求法

在没有负边权的情况下,我们一般使用两次DFS求树的直径:

  1. 第一次DFS从任意位置出发,找到距离起点最远的点x , x x,xxx是一条直径的端点之一;
  2. 第二次DFS从点x xx出发,找到距离点x xx最远的点y yyx xxy yy的路径即为一条直径。

树形DP

当图中存在负边权时,无法使用DFS算法求解最长路径。此时应采用树形DP方法:首先选取任意节点作为根节点,对于每个节点x xx,计算其子树中以x xx为顶点的最长路径。该路径长度等于x xx向下的最长路径与次长路径之和。在DFS遍历过程中,只需维护这两个路径长度信息即可完成计算。

实现

voiddfs(intu,intfa){d1[u]=d2[u]=0;//d1是最长路,d2是次长路for(intv:E[u]){if(v==fa)continue;dfs(v,u);intdv=d1[v]+1;if(dv>d1[u]){d2[u]=d1[u];d1[u]=dv;}elseif(dv>d2[u]){d2[u]=dv;}}ans=max(ans,d1[u]+d2[u]);}

树的重心

要确定树的重心,需选择一个根节点使其子树分布尽可能均匀。这里用最大子树的节点数来衡量均匀程度——该数值越小,分布越均匀。因此,使最大子树节点数最小的根节点即为树的重心。

性质

  1. 树的重心最多只有两个,若有两个一定相邻。
  2. 以重心作为根节点,根节点的最大子树节点数不会超过n / 2 n/2n/2
  3. 树上所有点到某个点的距离之和中,到重心的最小。
  4. 把两棵树用一条边连起来,形成的新的树的重心在原来两树重心之间的路径上。
  5. 在一颗树上添加一个叶子节点,重心最多向叶子节点移动一条边。

求法

以任意节点为根进行DFS遍历,可以计算每个节点的子树规模。具体而言:

  1. 向下递归时统计各子树节点数
  2. 向上部分的大小可通过公式n-size[cur]求得

实现

voiddfs(intx,intfa){for(intv:E[x]){if(v==fa)continue;dfs(v,x);sz[x]+=sz[v];mx[x]=max(mx[x],sz[v]);//向下子树大小}sz[x]++;mx[x]=max(mx[x],n-sz[x]);//向上子树大小}

树的中心

树的中心指的是树中某个特殊节点,当以其为根时,能使得从该节点出发的最长路径长度达到最小。它具有以下关键特性:

  1. 树的中心数量不超过两个,且若存在两个中心则必定相邻
  2. 中心必然位于树的直径路径上
  3. 中心到任意节点的距离不超过树直径的一半
  4. 所有节点到其最远点的路径必然经过中心

求解步骤:

  1. 计算最长路径:采用深度优先搜索(DFS)算法,为每个节点计算其作为根时的最长路径和次长路径
  2. 计算外部路径:通过换根动态规划技术,计算每个节点在其子树之外的最长路径
  3. 确定中心节点:对每个节点求取其最长路径与外部路径的最大值,其中最小值对应的节点即为树的中心
#include<bits/stdc++.h>usingnamespacestd;vector<int>E[100005];intn,dp1[100005],dp2[100005],p1[100005],p2[100005],up[100005];voiddfs(intx,intfa){for(inti=0;i<E[x].size();i++){intv=E[x][i];if(v==fa)continue;dfs(v,x);ints=dp1[v]+1;if(s>dp1[x]){dp2[x]=dp1[x];dp1[x]=s;p2[x]=p1[x];p1[x]=v;}elseif(s>dp2[x]){dp2[x]=s;p2[x]=v;}}}voiddfs1(intx,intfa){for(inti=0;i<E[x].size();i++){intv=E[x][i];if(v==fa)continue;if(v==p1[x]){up[v]=max(dp2[x],up[x])+1;}else{up[v]=max(dp1[x],up[x])+1;}dfs1(v,x);}}intmain(){cin>>n;for(inti=1;i<n;i++){intu,v;cin>>u>>v;E[u].push_back(v);E[v].push_back(u);}dfs(1,0);dfs1(1,0);intmn=INT_MAX;for(inti=1;i<=n;i++){mn=min(mn,max(dp1[i],up[i]));}for(inti=1;i<=n;i++){if(max(dp1[i],up[i])==mn){cout<<i<<" ";}}return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 1:05:35

操作指南:如何在紧凑空间完成高效PCB布局设计

在30mm内塞进智能手表主板&#xff1f;揭秘高密度PCB布局的硬核实战你有没有试过在一块比指甲盖还小的电路板上&#xff0c;塞进主控芯片、无线模块、传感器阵列和电源管理系统&#xff1f;这不是科幻场景——而是如今每一块智能手表、TWS耳机甚至微型医疗贴片的真实写照。随着…

作者头像 李华
网站建设 2026/6/9 1:39:32

应急响应预案演练:关键时刻不慌乱

应急响应预案演练&#xff1a;关键时刻不慌乱 在一场突如其来的数据中心断电事故中&#xff0c;值班主管冲到控制台前&#xff0c;手心冒汗——他需要立刻确认备用电源切换流程、通知哪些负责人、是否触发上级应急预案。然而&#xff0c;厚厚的《IT基础设施应急手册》有200页&a…

作者头像 李华
网站建设 2026/6/9 21:27:05

18、Windows系统注册表分析与恶意软件检测全解析

Windows系统注册表分析与恶意软件检测全解析 注册表分析 在Windows 7系统中,注册表蕴含着大量有价值的信息。以下是对注册表分析的详细介绍: 1. 历史用户活动数据 :UserAssist子键中的信息能显示用户活动,但仅为最近一次活动情况。例如,看到用户启动某应用14次,只能…

作者头像 李华
网站建设 2026/6/10 1:10:21

易思维通过注册:前9个月营收2亿 净亏654万 拟募资12亿

雷递网 雷建平 12月22日易思维&#xff08;杭州&#xff09;科技股份有限公司&#xff08;简称&#xff1a;“易思维”&#xff09;日前通过注册&#xff0c;准备在科创板上市。易思维计划募资12.1亿元&#xff0c;其中&#xff0c;7.05亿元用于机器视觉产品产业化基地项目&…

作者头像 李华
网站建设 2026/6/8 20:08:31

RPO数据丢失容忍:备份策略制定依据

RPO数据丢失容忍&#xff1a;备份策略制定依据 在AI驱动的知识管理系统中&#xff0c;一次意外的服务中断可能意味着数小时的文档处理成果付诸东流。想象一下&#xff0c;团队刚完成一份重要行业报告的向量化入库&#xff0c;系统突然宕机——如果没有合理的恢复机制&#xff0…

作者头像 李华
网站建设 2026/6/8 19:45:34

使用SPICE仿真分析同或门电气特性项目应用

揭秘同或门的“真实一面”&#xff1a;用SPICE仿真看透数字电路背后的电气真相你有没有遇到过这样的情况&#xff1f;RTL仿真一切正常&#xff0c;逻辑功能完美无误&#xff0c;综合时序也过关——结果一上板&#xff0c;系统在高温下频繁出错&#xff0c;或者低电压时比较器莫…

作者头像 李华