码迷,mamicode.com
首页 > 其他好文 > 详细

[常见做法整合]CSP-S2019 D2T3 树的重心

时间:2020-03-31 17:23:59      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:log   倍增   判断   com   完成   soa   树状数组   图论   超过   

CSP-S2019 D2T3 树的重心(centroid)

本题解是题解栏内一些常见思路的集合。

为了篇幅紧凑,在一些地方我可能跳过了证明/阐述的不是怎么详细,如果希望看到某一个思路的详细阐述/代码,可以点击相关的超链接。

思路

本题的部分分启发我们去找性质:

  1. 链的部分分启发我们去考虑树链剖分
  2. 二叉树的部分分启发我们去考虑以重心为根的情况。
  3. 由于要同时考虑子树与外子树的情况,这启发我们想到换根法

性质:

  1. 重心\(u\)在根节点所在的重链上。
  2. \(u\in son_{rt}\)\(v\)\(u\)的重心,则\(rt\)的重心为\(v\)的祖先。
  3. \(u\)为重心,只有\(u\)的重儿子(或父亲)有可能是重心。

计数方法:

  1. 对于每一个点,我们计算它作为重心的次数:这会导致实现偏向数据结构(BIT、可持久化线段树、树状数组等)。
  2. 对于每一个分割,我们去找两课树的重心:这回导致实现偏向图论类方法(树链剖分、找重儿子、倍增等)。

方法0:考虑点,只考虑定义

代码 类似思路的题解

考虑一个点\(u\),我们想要知道,它会成为几次重心。

将树在\(u\)处定根,设其最大的子树大小为\(S=siz_w\),则可以分为两种情况:

  1. 删去的边不在\(tree_w\)中,\(tree_v\not\subseteq tree_w\):则\(siz_v\le n-2S\)时,\(u\)成为重心。
  2. 删去的边在\(tree_w\)中:设除了\(tree_w\)最大的子树大小为\(T\),则\(2S-n\le siz_v\le n-2T\)\(u\)成为重心。

因此,我们考虑处理出以\(u\)为根,各个儿子的\(\{siz\}\)的可重集合的情况,再查询一段区间内的\(siz\)的个数即可。

维护方法

可以用可持久化线段树(可能可以线段树合并/将所有查询离线化)维护。

特别地,\(fa_u\)的情况,相当于\(tree-anc_u-tree_u\)\(\{u\}+anc_u-\{rt\}\)取反。(其中,\(anc_u\)表示\(u\)的所有祖先节点)

方法1:考虑点,以重心为根

我们先找到重心\(rt\),并以它作为根。这样和随意选根有什么区别呢?

性质:若\(x\ne rt\)为重心,则删去的边\((u,v)\)一定不在\(tree_x\)内。

因此,对一个点\(u\ne rt\),他作为重心仅当删去了一条边\((x,y)\),且:\((x,y)\)不在\(tree_u\)内,\(n-2s_x\le S\le n-2g_x\)。(设树减少的大小为\(S\)

对于根的情况,可以另外(分成割去的边在重儿子子树内与不在重儿子子树内)判断。

可以用树状数组维护,具体见这篇题解

方法2:考虑边

考虑一种删边情况,我们需要快速求出,划分后的所有重心。

考虑如何求一棵树的重心:因为重心一定在根节点所在重链上,从根一直跳重儿子,直到找到最深的\(v\)使得,\(2s_v > s_u\),则\(v\)(可能还有它的重儿子)为重心。此过程可以用倍增加速。

由这种做法,我们可以在树链剖分,并预处理倍增数组之后\(O(\log n)\)地求出任何子树的重心。

高赞题解的变体

我们考虑一个划分\((u,v)\),不妨设\(dep_u>dep_v\)

考虑如何求\(tree_u\)的重心:我们从\(u\)出发,一直向重儿子跳,跳到找到重心(即,重儿子的子树大小不超过原树的一半)为止。

考虑如何求出\(tree-tree_u\)的重心:我们先将根换到\(v\)处(此时只改变了两个节点的关系),这样实际上就相当于求\(tree_u\)的重心!

具体实现在

方法3:考虑边,某神奇的\(O(n)\)做法

就如之前所说的,可以在\(O(n)\)计算出所有子树的重心,但是很难对去掉子树的部分找到一个重心单调移动的计算序列……

以重心为根,考虑删去的边在哪棵子树内:

  1. 不在重儿子的子树内:则枚举所有可能的子树大小,在根所在的重链上面走就好了。
  2. 在重儿子的子树内:
    1. 重儿子仍然为重儿子:此时,根仍然为重心。
    2. 次重儿子变为了重儿子:在次重儿子的重链上走即可。

这样就用纯图论方法完成了这题。

参考资料

[常见做法整合]CSP-S2019 D2T3 树的重心

标签:log   倍增   判断   com   完成   soa   树状数组   图论   超过   

原文地址:https://www.cnblogs.com/topsecret/p/12606466.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!