树的重心---解释和模板

树的重心

使用背景: 对一颗无根树,求重心.(当然,对一棵树,究竟是有根还是无根,完全自己说了算),

感性定义: 作为根时,能使各子树节点数目"均衡"的节点。

明确定义: f ( x ) f(x) f(x)表示节点 x x x为根时,所有的子树节点个数中的最大值。 f ( x ) f(x) f(x)最小的节点即这颗无根树的重心。

性质:

  1. 以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。
  2. 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。
  3. 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。
  4. 在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。

求法: 在 DFS 中计算每颗子树的大小,记录“向下”的子树的最大大小,利用总点数 - 当前子树(这里的子树指有根树的子树)的大小得到“向上”的子树的大小,得出当前节点的 f ( x ) f(x) f(x),根据定义,更新重心。

vector<int> tree[maxn];
int rt, sbsz = INT_MAX;
int n;
void getCentroid(int u, int f, int &sz)
{
	sz = 1;
	int maxsubtree = 0;
	for (auto v : tree[u])
	{
		if (v == f)continue;
		int temp;
		getCentroid(v, u, temp);
		sz += temp;
		if (temp > maxsubtree)maxsubtree = temp;
	}
	maxsubtree = max(maxsubtree, n - sz);
	if (maxsubtree < sbsz)rt = u, sbsz = maxsubtree;
}

复杂度分析: 只使用了一遍dfs,复杂度为 O ( v + e ) O(v + e) O(v+e)

拓展: 感性定义中,提到了“均衡”, 这里的均衡是指子节点数目的均衡,那么,是否可以用类似的dfs求叶子节点数目的均衡?求边权总和的均衡?答案是可以的,只需要改变sz的求法就可以了。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值