ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树的重心

2022-06-25 11:35:26  阅读:170  来源: 互联网

标签:sz 子树 重心 ctr int 一棵树


一、树的重心的定义:
在一棵树中,如果我们选择某个结点为根,可以使得它的所有子树中最大的子树最小,那么这个结点就被称作这棵树的重心。

二、树重心的性质:
1.以重心为树根时,所有子树的大小不超过全树大小的一半。

2.如果树的所有边权都为1,那么树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。反过来,距离和最小的点一定是重心。

3.把两棵树通过一条边相连得到一棵新的树,则新的重心在较大的一棵树一侧的连接点与原重心之间的简单路径上。如果两棵树大小一样,则重心就是两个连接点。
另外一种说法:把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。

4.在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。

5.一颗树最多只有两个重心,且这两个重心一定是相邻的。此时树一定有偶数个节点,且可以被划分为两个大小相等的分支,每个分支各自包含一个重心。

6.一棵树的重心一定在根节点所在的重链上。

7.一棵树的重心一定是以该树根节点重儿子为根的子树的重心的祖先。

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

三、找重心
遍历树,对每个点求 \(f_u\) 表示最大子树。边遍历边求最小 \(f_u\)。

代码:

inline void dfs(int u, int fa)
{
	sz[u] = 1;
	int v;
	for(int e = hd[u]; e; e = nt[e])
	    if((v = to[e]) ^ fa)
		{
		    dfs(v, u);
		    sz[u] += sz[v];
		    f[u] = max(f[u], sz[v]);
		}
	f[u] = max(f[u], n - sz[u]);
	if(!ctr || f[u] < f[ctr] || (f[u] == f[ctr] && u < ctr)) ctr = u;
}

标签:sz,子树,重心,ctr,int,一棵树
来源: https://www.cnblogs.com/fakeryu/p/16410984.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有