首页 > 其他分享 >Living-Dream 系列笔记 第64期

Living-Dream 系列笔记 第64期

时间:2024-07-24 17:44:07浏览次数:9  
标签:Living cur ctr int siz 64 重心 Dream mx

树的重心

当 \(u\) 作为根时,其节点数最大的子树最小,则称 \(u\) 为树的重心。

  • 性质一:节点数最大的子树的节点数不超过 \(\frac{节点总数}{2}\)。

    (反证法,若某重心 \(u\) 的节点数最大的子树的节点数超过 \(\frac{节点总数}{2}\),则将其一个子节点提起来会更优)

  • 性质二:至多两个且一定相邻。

    (反证法,若不相邻或不止两个,则将中间的某个提起来会更优)

  • 性质三:树上增 / 删一个叶子,重心至多偏移一位。

  • 性质四:树上其他节点到重心距离和最小,若有两个,则到两个的距离和相等。

  • 性质五:两棵树连一条边,新树的重心一定位于原两重心的路径上。

    (同性质二,中间的提起来会更优)

P1395

板子。

code
#include<bits/stdc++.h>
using namespace std;

const int N=5e4+5;
int n,ans;
bool vis[N];
vector<int> G[N],ctr;
int siz[N],mx[N];

void get_ctr(int cur,int fa){
	siz[cur]=1;
	for(int i:G[cur]){
		if(i==fa) continue;
		get_ctr(i,cur);
		siz[cur]+=siz[i];
		mx[cur]=max(mx[cur],siz[i]);
	}
	mx[cur]=max(mx[cur],n-siz[cur]);
	if(mx[cur]*2<=n) ctr.push_back(cur);
}
void dfs(int cur,int fa,int sum){
	ans+=sum;
	for(int i:G[cur]){
		if(i==fa) continue;
		dfs(i,cur,sum+1);
	}
}

int main(){
	cin>>n;
	for(int i=1,u,v;i<n;i++)
		cin>>u>>v,
		G[u].push_back(v),
		G[v].push_back(u);
	get_ctr(1,0);
	sort(ctr.begin(),ctr.end());
	dfs(ctr[0],0,0);
	cout<<ctr[0]<<' '<<ans;
	return 0;
}

CF685B

我们从下往上求出每棵子树的重心。

对于任意点 \(cur\),其所在子树的重心,一定位于 \(cur \to ans_{nxt}\) 的链上(\(ans_{nxt}\) 表示 \(cur\) 的最大子树 \(nxt\) 的重心)。

于是我们令 \(tmp\) 从 \(ans_{nxt}\) 开始不断向上跳(为了使上方子树更小),直到 \(size_{tmp} \ge \frac{size_{cur}}{2}\)(此时 \(tmp\) 为根,\(cur\) 为 \(tmp\) 的子树,于是 \(tmp\) 不能受 \(cur\) 的约束)即为重心。

点击查看代码
#include<iostream>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;

const int N=3e5+5;
int t,n,q;
int ans[N],son[N],faa[N];
vector<int> G[N];
int siz[N],mx[N];

void get_ctr(int cur,int fa){
	siz[cur]=1;
	for(int i:G[cur]){
		if(i==fa) continue;
		get_ctr(i,cur);
		siz[cur]+=siz[i];
		if(mx[cur]<siz[i])
			mx[cur]=siz[i],
			son[cur]=i;
	}
	mx[cur]=max(mx[cur],n-siz[cur]);
	if(!son[cur]){ ans[cur]=cur; return; }
	int tmp=ans[son[cur]];
	while(siz[tmp]*2<siz[cur]) tmp=faa[tmp];
	ans[cur]=tmp;
}

int main(){
	ios::sync_with_stdio(0);
	cin>>n>>q;
	for(int i=2,u;i<=n;i++)
		cin>>u,
		G[u].push_back(i),
		faa[i]=u;
	get_ctr(1,0);
	while(q--){
		int v; cin>>v;
		cout<<ans[v]<<'\n';
	}
	return 0;
}

CF1406C

若重心只有一个,则随便上一条边再加回去。

若重心有两个,根据重心的性质四,就把一个重心的子树内的某一叶子节点连边放到另一个重心的子树里去即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5;
int t,n;
vector<int> G[N],ctr;
int siz[N],mx[N];
int ans1,ans2,ans3;

void get_ctr(int cur,int fa){
	siz[cur]=1;
	for(int i:G[cur]){
		if(i==fa) continue;
		get_ctr(i,cur);
		siz[cur]+=siz[i];
		mx[cur]=max(mx[cur],siz[i]);
	}	
	mx[cur]=max(mx[cur],n-siz[cur]);
	if(mx[cur]*2<=n) ctr.push_back(cur);
}
void dfs(int cur,int fa,bool f){
	if(G[cur].size()==1){
		if(f) ans1=cur,ans2=fa;
		else ans3=cur;
		return;
	}
	for(int i:G[cur]){
		if(i==fa) continue;
		dfs(i,cur,f);
	}
}
void init(){
	ctr.clear();
	for(int i=1;i<=n;i++) G[i].clear();
	memset(siz,0,sizeof siz);
	memset(mx,0,sizeof mx);
	ans1=ans2=ans3=0;
}
void sol(){
	init();
	cin>>n;
	for(int i=1,u,v;i<n;i++)
		cin>>u>>v,
		G[u].push_back(v),
		G[v].push_back(u);
	get_ctr(1,0);
	if(ctr.size()==1){
		cout<<ctr[0]<<' '<<G[ctr[0]][0]<<'\n'<<ctr[0]<<' '<<G[ctr[0]][0]<<'\n';
		return;
	}
	//cout<<ctr[0]<<' '<<ctr[1]<<'\n';
	dfs(ctr[0],ctr[1],1);
	//dfs(ctr[1],ctr[0],0);
	cout<<ans1<<' '<<ans2<<'\n'<<ctr[1]<<' '<<ans1<<'\n';
}

int main(){
	cin>>t;
	while(t--) sol();
	return 0;
}

标签:Living,cur,ctr,int,siz,64,重心,Dream,mx
From: https://www.cnblogs.com/XOF-0-0/p/18321369

相关文章

  • Living-Dream 系列笔记 第63期
    树的中心当选取树上节点\(u\)为根时,最长链最短,则称\(u\)为树的中心。性质一:至多\(2\)个且一定相邻。性质二:一定位于树的直径上。性质三:若一棵树有多条直径,则它们必定交于树的中心。性质四:树的中心为根时,根到直径两端点分别为最长/次长链。U392706板子。......
  • 边缘设备使用记录--阿加犀AIBox 6490(realsense+yolox部署)
    边缘设备使用记录--阿加犀AIBox6490:realsense+yolox部署前言RealsenseSDK+ROSYOLOx部署预处理后处理可视化ROS节点总结前言由于6490这个板子是有type-c接口的,所以这里准备用Realsense+YOLOx来先简单做一个实时的目标检测的东西出来,这里也用到上一篇文章所提到......
  • WIN7X64SP1极限精简版by双心
    WIN7X64SP1极限精简版by双心http://bbs.wuyou.net/forum.php?mod=viewthread&tid=405044&page=1&extra=#pid3534155http://www.cnblogs.com/liuzhaoyzz/p/7774511.htmlWIN7X64SP1极限精简版by双心 下载地址1:https://cloud.189.cn/t/UvQF73QVbURz下载地址2:链接: https://pan.ba......
  • H264 NALU
    H.264是一种广泛使用的视频压缩标准,全称是MPEG-4Part10AVC(AdvancedVideoCoding)。它通过有效的压缩技术,能够在较低的比特率下提供高质量的视频。以下是对H.264的一些关键概念和工作原理的详细讲解:1.编码原理H.264采用帧内和帧间预测技术来压缩视频数据。它将视频分为若干......
  • 第四十七天 第九章 动态规划part13 647. 回文子串 516.最长回文子序列
    647.回文子串 dp和双指针。dp[i][j]的含义:表示区间范围[i,j](注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。在确定递推公式时,就要分析如下几种情况。整体上是两种,就是s[i]与s[j]相等,s[i]与s[j]不相等这两种。当s[i]与s[j]不相等,那没啥好说的......
  • Living-Dream 系列笔记 第62期
    树的直径:定义:树上两个距离最远的点形成的简单路径(不重复走一条边/点)性质:不唯一。树的直径的端点一定是度数为\(1\)的点。证明:显然。树的直径若有多条,则必交汇于一点,即中心。证明:首先每条直径只能交于端点(因为是一棵树,一个节点不能有两个父节点),然后此交点必定......
  • 1323、基于51单片机按键发送GPS时间定位信息 GSM短信收LCD12864显示报警(程序+原理图+
    毕设帮助、开题指导、技术解答(有偿)见文未  目录方案选择单片机的选择一、设计功能二、实物图单片机模块设计三、原理图四、程序源码五、PCB图资料包括:需要完整的资料可以点击下面的名片加下我,找我要资源压缩包的百度网盘下载地址及提取码。方案选择单片机的......
  • [namespace hdk] 64位 bitset
    功能已重载运算符[](int)~()+(bitset)+(unsignedlonglong)+=(bitset)+=(unsignedlonglong)>==<>=<=(bitset\unsignedlonglong)<<>>max()min()已定义函数intsize()返回bitset大小intarray_size()返回bitset占用的unsigned_longlong......
  • P6475 [NOI Online #2 入门组] 建设城市
    P6475[NOIOnline#2入门组]建设城市传送门分类讨论:设\(f(x,y)\)为\(C^{j-1}_{i+j-1}\)\(x,y\)在同一旁把\(x,y\)之间的看成一个高楼公式\(f(n,m)\timesf(n+x-y,m)\)\(x,y\)在异侧枚举\(x,y\)高楼的高度\(h\)\(\displaystyle\sum^{n}_{i=1}f(x-1,i)*f(n-x,m-i......
  • arm64环境部署rocketmq
    arm64环境部署rocketmq(x86架构同理)1.编译rocketmq镜像拉取代码gitclonehttps://github.com/apache/rocketmq-docker.git安装docker-compose略编译镜像进入image-build目录cdrocketmq-docker/image-build修改arm环境支持的基础镜像vimDockerfile-alpine将......