【JZOJ6435】【luoguP5666】【CSP-S2019】树的重心

这篇博客讨论了如何在树形结构中找到重心,通过树链剖分和倍增算法来高效实现。首先确定重链上的节点,然后利用深度信息判断重心。当断开边(x, y)时,需要分别计算y子树和剩余树的重心。通过递归和换根操作,可以在O(nlogn)的时间复杂度内完成。" 133498828,7337247,理解机器学习中的损失函数,"['机器学习', '模型训练', '损失函数', '分类问题', '回归问题']

description


analysis

  • 需要知道一棵树的重心一定在从根出发的重链上,可以考虑先进行树链剖分弄出重儿子和次重儿子,再倍增维护重儿子

  • 由于重链上有一个或两个重心,接下来求的重心都是深度较大的,只需判断其父节点是否也满足重心的性质即可

  • 现在要断掉一条边(x,y)(x,y)(x,y),假设xxxyyy的父亲,需要分别求出yyy的子树的重心、以及除了yyy的子树以外的树的重心

  • 倍增数组已经维护好了所以yyy的重心很好求,对于视作xxx为根的子树则需要重新维护一次倍增数组

  • yyy是重儿子则用次重儿子与xxx父亲sizesizesize比较,否则用原来的重儿子比;知道了重儿子则可以重新算倍增数组

  • 然后把xxx设为yyy的儿子,其实就是换根操作,递归下去求解,回溯时重新再算xxx的倍增数组;时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)


code

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define MAXN 300005
#define MAXM MAXN*2
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=las[a];i;i=nex[i])

using namespace std;

ll las[MAXM],nex[MAXM],tov[MAXM];
ll fa[MAXN],size[MAXN],tsize[MAXN],hson[MAXN],secson[MAXN]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值