当前位置: 首页 > news >正文

求树的重心

题目:

给定一颗树,树中包含 n个结点和 n−1条无向边。树的重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小。请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。

思路:

用邻接表存储树,同时用一个数组保存以每个结点为根的子树大小(图中红色框部分),递归DFS遍历树,在回溯阶段计算删除该结点后它所有的子树大小和“上面剩余部分”的大小,取最大的那块记为maxPart,取所有结点中最小的那个maxPart记为minMaxPart,其对应的结点就是树的重心。

代码:

#include<iostream>
#include<vector>
#include<cmath>
#include<climits>
using namespace std;int n;
vector<vector<int>> tree;//邻接表-树
vector<int> subtreeSize; //每个结点作为根的子树大小
int minMaxPart = INT_MAX;
vector<int> centroids;// 所有重心void dfs(int u, int parent)
{subtreeSize[u] = 1;//先把自己算上int maxPart = 0;//最大子块for (int v : tree[u]){//这一步很关键:其实无所谓parent,图也可以这么处理,这个parent其实是递归上一层的那个结点//这么做是为了把邻居结点分成两部分(1)递归上一层的结点(2)接下来要去的那些结点//这样subtreeSIze也才有了意义,它是接下来要去的那些结点“引领”的块的大小if (v == parent) continue;dfs(v, u);subtreeSize[u] += subtreeSize[v];maxPart = max(maxPart, subtreeSize[v]);//寻找最大子块}int upPart = n - subtreeSize[u];//把u作为根节点时,它的父节点那一块也成了一个子块maxPart = max(maxPart, upPart);if (maxPart < minMaxPart){minMaxPart = maxPart;centroids.clear();centroids.push_back(u);}else if (maxPart == minMaxPart){centroids.push_back(u);}
}int main()
{cin >> n;tree.resize(n + 1);//结点从1开始标记subtreeSize.resize(n + 1);for (int i = 1; i < n; i++){int u, v;cin >> u >> v;tree[u].push_back(v);tree[v].push_back(u);}dfs(1, 0); //从结点1开始dfs(任选)cout << "树的重心是:";for (int u : centroids)cout << u << " ";cout << endl << "删除后最大块大小:" << minMaxPart << endl;return 0;
}

运行结果:

 

复杂度:

时间复杂度:O(n),dfs

空间复杂度:O(n),邻接表

(本来是O(v+e)的,由于是树,e = v - 1,所以O(n) )

http://www.xdnf.cn/news/591859.html

相关文章:

  • 关于fastjson与fastjson2中parseObject操作的区别
  • Python 实现Web 请求与响应
  • 背包问题(1)
  • Java RestTemplate 通用请求工具类
  • 2024游戏安全白皮书:对抗激烈!PC游戏外挂功能数增长超149%,超85%移动外挂为定制挂(附获取方式)
  • 基于阿里云DashScope API构建智能对话指南
  • 写一个计划任务脚本(定时执行)
  • PostgreSQL跨数据库表字段值复制实战经验分
  • 对于从事FPGA行业的人来说,需要掌握哪些知识
  • ant design 日历组件a-calendar如何汉化
  • 二分算法的补充说明
  • 表格单元格多行文本溢出写法
  • 基于SpringBoot的美食分享平台设计与开发(Vue MySQL)
  • 高效数据库管理新体验:SQLynx 3.7 功能解析与团队协作场景实践
  • 06算法学习_58. 区间和
  • PrimeVue菜单组件深度解析:构建高效能的Web导航系统
  • 3 tomcat原理
  • 多元回归的假设检验
  • Linux中 I/O 多路复用机制的边缘触发与水平触发
  • 鸿蒙运动开发:计算户外运动步频与步幅,与地图路线绘制
  • 链表-环形链表||
  • 3.8.2 利用RDD计算总分与平均分
  • Java 多线程编程:解锁高性能应用开发的密钥
  • RAG系统实战:文档切割与转换核心技术解析
  • Golang 访问 map 中的结构体字段时如何避免拷贝
  • 无anaconda搭建yolo11环境
  • 鸿蒙进阶——CMakelist、GN语法简介及三方库通用移植指南
  • 技术篇-2.3.Golang应用场景及开发工具安装
  • 晶振选型三大陷阱:工作温度、电压与负载电容的隐藏矛盾
  • 【AT32】 at32 软复位