POJ 1741:点分治详解

博客介绍了点分治算法在解决树上路径统计问题的应用,特别是针对POJ 1741题目。点分治通过选择树的重心来有效地分解树,减少规模并加速计算。文章详细解释了如何计算经过特定点的路径,并在每个阶段删除该点以继续分治。最后,提到了不同题目中统计经过某点路径的方法会有所不同,但点分治的基本思路保持一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给出一个n(<=1e4)个点的树,每条边有权,求树上长度小于等于k的路径条数。(u,v)和(v,u)算两条。


点分治:顾名思义,点分治就是对点进行分治,一般用于路经统计问题。对每个点而言,一条路径要么经过他,要么不经过他,这就是分,即分成路径经过此点和不经过此点。基本思想是:当经过某点的路径可以比较方便快速统计的情况下,通过对点进行分治,把树的规模不断变小。


考虑这样做的好处:把树看作无根树,除了叶子结点外,去掉任意一个点,都可以把一棵树分裂成若干规模更小的树。然后先统计好经过此点的路径,然后只需要统计不经过此点的路径,那么就等价于把这个点删掉,所以只要复杂度合理,点分治是普遍适用的。


关于点的选取:考虑最坏情况:一条链,如果顺序选取,可能会出现每次都选了链的端点,那么点分治本来是想通过对点进行分治,把一棵大树,分解成几棵小树,分而治之。那么如果随意选点,很可能对点分治之后,分解出的树规模和刚刚的差不多,导致效率极低。


树的重心:一棵无根树,对于某个点,把他去掉之后,原树会分裂成几棵小树,每个小树有若干个节点。树的重心就是一个点,去掉他之后,裂开后得到的最大的小树规模最小,显然,点分治中,对树的重心进行分治是最好的。他可以稳定的把树的规模不断变小。


一般套路:对整个树(联通快),求出一个重心,对重心这个点进行分治,先统计出经过这个点的路径。然后把这个点删掉。把整个树分解成小树(联通快)。对每个小树(联通快)继续求重心,继续进行分治。


题解:考虑某个点x,经过x且长度小于等于k的路径个数可以很方便求出:把树变成x为根的树,对每个点求出x到他的距离,然后双指针进行组合。但是有一个后果:某个经过x的路径可以分成两段,这两段必须分布在两个子树上,如果在一个子树上,他们的LCA不等于x,也就是不会经过x,上面统计完成之后,还要对每个子树进行去重,文末的代码更容易理解。想清楚经过某点的路径如何统计之后,那么就可以按照上面点分治的套路搞了。


个人感觉点分治就是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值