c++树(三)重心

news2024/11/15 7:40:09

目录

重心的基础概念

定义:使最大子树大小最小的点叫做树的重心

树的重心求解方式

例题:

重心的性质

性质1:重心点的最大子树大小不大于整棵树大小的一半。

性质1证明:

性质1的常用推导

推导1:

推导2:

性质2:非空树有且仅有1-2个重心。当有两个重心时,树定有偶数个节点,且两个重心相邻。

性质2证明:

性质3:树中所有点到重心的距离和最小,反过来距离和最小的点一定是重心。

性质4:往树上增加或减少一个叶子,如果原节点数是奇数,那么重心可能增加一个,原重心仍是重心;如果原节点数是偶数,重心可能减少一个,另一个重心仍是重心。

性质5:把两棵树通过一条边相连得到一棵新的树,则新的重心在较大的一棵树一侧的连接点与原重心之间的简单路径上。如果两棵树大小一样,则重心就是两个连接点。

总结回顾:

一、重心的基础概念与求解方法

二、树的重心的三个基础性质


重心的基础概念

定义:使最大子树大小最小的点叫做树的重心

        在线性的序列[1,n]中,我们在考虑用分治 思想处理问题时,需对问题进行划分。 在划分问题时若要更加均匀,我们选择中 点mid可以更加高效。 这样得到[1,mid],[mid+1,n]两个子序列, 因为子序列中元素的个数

        思考:在树中我们同样可以选择一个点,将该点及该点连 边删除后得到一些子树,那么要使得问题更加均匀的划分, 选的点应具备什么要的性质?

树的重心求解方式

        要求树的重心,我们可以枚举出每个点为断点时,所产生的最大子树大小。 某断点求当前最大子树大小的方法:对该点进行dfs,找到以i为根节点的子树的大小记录到sz[i]中,接着在该点的儿子中 找si最大的一个。复杂度为O(n2)

        仔细分析:一次dfs,可以将每个节点x的子树分为两种:

1.根节点将要去的子树。(dfs回溯时一定能获取类型1子树大小)

2.来时的子树,此时无法再递归回去。(假设断开来边,来时子树大小=总节点数-接下来获得的sz[x],即等于n-sz[x])意味着一次dfs能够求出所有点作为重心能得到的最大子树大小mss。我们取最小值即可,复杂度O(n)

例题:

给定一棵树,树中包含 n(n)个结点(编号1~n)和 n−1 条无向边,找出树的重心若重心不止一个, 则输出编号较小的),以及当前重心下的最大子树大小。

#include<bits/stdc++.h>
using namespace std;
int n;
const int N=1e5+5;
vector<int>v[N];
int sz[N];    //当前节点的子树大小
int jie,minn=N;//jie是重心,minn为重心下的最大子树大小
void dfs(int x,int fa){
	sz[x]=1;
	int res=0;//开始找到当前x为根的最大子树
	for(int i=0;i<v[x].size();i++){
		int y=v[x][i];
		if(y==fa) continue;
		dfs(y,x);
		sz[x]+=sz[y];
		res=max(sz[y],res);  //在几个子树中找最大值
	}
	res=max(res,n-sz[x]);//去的子树算完后,剩下来时子树
	if(minn>res)minn=res,jie=x; 
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	dfs(1,0);
	cout<<jie<<" "<<minn;
}

重心的性质

树的重心与直径端点,树的中心一样,在解决树上问题时,我们经常会用到。当边权为1时,树的重心存在以下性质。设mss(u)表示以u为重心的最大子树,s0(u)表示以u为根的子树大小,su(v)表示以u为根的的子树v大小。

性质1:重心点的最大子树大小不大于整棵树大小的一半。

性质1证明:

设u为重心,v为u的最大子树。

可以得出:s0[u]-su[v]>=su[v] ,即 su[v]0[u]/2

在整颗树中,存在s [u]=n0,所以su[v]

以某点为根,最大子树大小不超过n/2的都是树的重心

性质1的常用推导

推导1:

以某点为根,最大子树大小不超过n/2的一定是树的重心。

推导2:

以root为根的有根树中,树的重心一定在其最大的一颗子树内。

具体来讲,假设y为root的最大子树的儿子,那么重心一定在tp[y]->root的这一条链中(tp[y]表示子树y的重心)

性质2:非空树有且仅有1-2个重心。当有两个重心时,树定有偶数个节点,且两个重心相邻。

性质2证明:

假设u、v为树上两个重心,u,v分别为对方最长链上的点。

此时:mss[u]=mss[v]

又设k为两个重心之间存在的点数。

由mss[u]=su[v]+k,mss[v]=sv[u]+k,推出

在k个点中选择中点p,此时,

mss[p]=max(su[v]+k/2,sv[u]+k/2) >=su[v]+k,当且仅当k=0时,不等式成立。

重心u、v之间必不可能有点。

所以若有两个重心,则重心必然相邻。

性质3:树中所有点到重心的距离和最小,反过来距离和最小的点一定是重心。

当前重心为u。mss[u]=s [v]u。

假设重心从u移动到v,mss[v]=sv[u],可得1类节点到重心的距离加1,2类节点到重心的距离减少1,因此当增加部分sv[u] 小于 减少部分 sv[u]时,距离和减少

所以当s [v]>s [u]时,重心移动,得到mss更小。反之若当前mss已经最小,则无法再产生一个更小距离和uv。

树的重心的一些拓展性质

性质4:往树上增加或减少一个叶子,如果原节点数是奇数,那么重心可能增加一个,原重心仍是重心;如果原节点数是偶数,重心可能减少一个,另一个重心仍是重心。

性质5:把两棵树通过一条边相连得到一棵新的树,则新的重心在较大的一棵树一侧的连接点与原重心之间的简单路径上。如果两棵树大小一样,则重心就是两个连接点。

总结回顾:

一、重心的基础概念与求解方法

概念:找到一个点,使得最大子树的值最小。

求解方法:一次dfs记录子树的大小,来边通过n-sz[]解决,可求出当前点的最大子树大小,记录能产生最大子树值最小的点。

二、树的重心的三个基础性质

性质1:重心点的最大子树大小不大于整棵树大小的一半。

性质2:非空树有且仅有1-2个重心。当有两个重心时,树定有偶数个节点,且两个重心相邻。性质3:树中所有点到重心的距离和最小,反过来距离和最小的点一定是重心。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《Milvus Cloud向量数据库指南》——开源许可证的范围:深入解析与选择指南

在开源软件的广阔天地中,开源许可证作为连接开发者与用户之间的重要法律桥梁,其类型多样且各具特色。每一种许可证都精心设计了特定的权限、限制和要求,旨在保护创作者的权益,同时促进软件的创新与共享。对于开发者和用户而言,深入理解并恰当选择适合的开源许可证,是确保…

C++树(四)二叉树

目录 二叉树的定义&#xff1a; 二叉树相关术语&#xff1a; 二叉树的概念与性质 二叉树基本性质 二叉树的节点数量 满二叉树概念&#xff1a; 完全二叉树概念&#xff1a; 完全二叉树性质&#xff1a; 二叉树的存储 二叉树的遍历 在此基础上&#xff0c;二叉树的遍历…

mac下010editor的配置文件路径

1.打开访达&#xff0c;点击前往&#xff0c;输入~/.config 2.打开这个文件夹 把里面的 010 Editor.ini 文件删除即可&#xff0c;重新安装010 Editor即可

有没有下面符合以下条件的电子时钟的代码

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

【React1】React概述、基本使用、脚手架、JSX、组件

文章目录 1. React基础1.1 React 概述1.1.1 什么是React1.1.2 React 的特点声明式基于组件学习一次,随处使用1.2 React 的基本使用1.2.1 React的安装1.2.2 React的使用1.2.3 React常用方法说明React.createElement()ReactDOM.render()1.3 React 脚手架的使用1.3.1 React 脚手架…

PostgreSQL使用(四)——数据查询

说明&#xff1a;对于一门SQL语言&#xff0c;数据查询是我们非常常用的&#xff0c;也是SQL语言中非常大的一块。本文介绍PostgreSQL使用中的数据查询&#xff0c;如有一张表&#xff0c;内容如下&#xff1a; 简单查询 --- 1.查询某张表的全部数据 select * from tb_student…

MSPM0G3507基于keil无法烧录的解决方法

在学习M0的板卡过程中&#xff0c;遇到了诸多玄学问题。网上的教学大多基于CCS开发&#xff0c;对keil的教学几乎没有。 一开始我以为这个问题是没添加这个&#xff0c;但其实并非如此 在群里的网友说的清除flash&#xff0c;插拔USB,这些都不管用,后面也发现先在CCS烧录一遍&…

前端开发知识(二)-css

<head> <style> div{ } </style> </head> div是布局标签&#xff0c; 一般放在head标签内&#xff0c;最下部。 若直接在在.css文件中写css,文件中&#xff0c;直接写就行&#xff0c;如下所示。 div{ }

VLLM代码解读 | VLLM Hack 3

在上一期&#xff0c;我们看到了多个输入如何被封装&#xff0c;然后被塞入llm_engine中&#xff0c;接下来&#xff0c;通过_run_engine,我们要进行输入的处理了。 def _run_engine(self, *, use_tqdm: bool) -> List[Union[RequestOutput, EmbeddingRequestOutput]]:# Ini…

java-poi实现excel自定义注解生成数据并导出

因为项目很多地方需要使用导出数据excel的功能&#xff0c;所以开发了一个简易的统一生成导出方法。 依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version…

【LeetCode】201. 数字范围按位与

1. 题目 2. 分析 这题挺难想的&#xff0c;我到现在还没想明白&#xff0c;为啥只用左区间和右区间就能找到目标值了&#xff0c;而不用挨个做与操作&#xff1f; 3. 代码 class Solution:def rangeBitwiseAnd(self, left: int, right: int) -> int:left_bin bin(left).…

五. TensorRT API的基本使用-TensorRT-network-structure

目录 前言0. 简述1. 案例运行2. 代码分析2.1 main.cpp2.2 model.cpp 总结下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习课程第五章—TensorRT API 的基本使用&#x…

java面向对象进阶进阶篇--《接口和接口与抽象类综合案例》(附带全套源代码)

个人主页→VON 收录专栏→java从入门到起飞 抽象类→抽象类和抽象方法 目录 一、初识接口 特点和用途 示例&#xff1a; Animal类 Dog类 Frog类 Rabbit类 Swim接口 text测试类 结果展示&#xff1a; 二、接口的细节 接口中的成员特点&#xff1a; 成员特点与接口的关…

【通信模块】WiFi&Bluetooth简介与对比

学习云里物里科技文章及结合CSDN优秀作者Edison Tao总结笔记&#xff0c;侵权联删&#xff01; 云里物里科技&#xff1a; https://www.minewtech.com/news/industry-2019-01-25-01.html CSDN&#xff1a; https://blog.csdn.net/taotongning/article/details/95215927 WIFI…

EXCEL 排名(RANK,COUNTIFS)

1.单列排序 需求描述&#xff1a;如有下面表格&#xff0c;需要按笔试成绩整体排名。 解决步骤&#xff1a; 我们使用RANK函数即可实现单列整体排名。 Number 选择第一列。 Ref 选择这一整列&#xff08;CtrlShift向下箭头、再按F4&#xff09;。 "确定"即可计算…

C++ | Leetcode C++题解之第284题窥视迭代器

题目&#xff1a; 题解&#xff1a; template <class T> class PeekingIterator : public Iterator<T> { public:PeekingIterator(const vector<T>& nums) : Iterator<T>(nums) {flag Iterator<T>::hasNext();if (flag) {nextElement Ite…

AUTOSAR从入门到精通-CAN-FD

目录 几个高频面试题目 CAN与CAN FD的区别是什么? 一、CAN与CAN FD的概念 二、CAN与CANFD的比较 三、CAN与CANFD的优劣势 为何CANFD还不能大面积取代CAN总线? 算法原理 什么是CAN FD CAN FD的特点 为什么会出现CAN FD? CAN FD和CAN总线协议帧异同 Can FD报文讲解…

调用python-docx 提示出错

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

【Django】 读取excel文件并在前端以网页形式显示-安装使用Pandas

文章目录 安装pandas写views写urls安装openpyxl重新调试 安装pandas Pandas是一个基于NumPy的Python数据分析库&#xff0c;可以从各种文件格式如CSV、JSON、SQL、Excel等导入数据&#xff0c;并支持多种数据运算操作&#xff0c;如归并、再成形、选择等。 更换pip源 pip co…

C#开发的全屏图片切换效果应用 - 开源研究系列文章 - 个人小作品

这天无聊&#xff0c;想到上次开发的图片显示软件《 PhotoNet看图软件 》&#xff0c;然后想到开发一个全屏图片切换效果的应用&#xff0c;类似于屏幕保护程序&#xff0c;于是就写了此博文。这个应用比较简单&#xff0c;主要是全屏切换换图片效果的问题。 1、 项目目录&…