前言
本文诣在实现NOI图论的全覆盖,各知识点以提纲的形式出现,未涉及具体原理及实现,但附有优质的讲解blog的网址,用于有一定算法基础的同学复习、巩固、加深。
Part1:点分治 & 点分树
一 . 点分治概述
- 点分治是一种在树上比较常用的分治方法,适用于一些树上的数据结构类问题。
-
算法大致流程:
- 求出当前部分树的重心
- 计算与当前重心相关的答案,如:经过该重心的路径条数、长度等。
- 删除重心,将当前部分树分成更多部分,重复上述操作。
- 代码
- 主要用处:处理路径信息,因为:
- 每次以重心分割树,可以处理经过当前重心的路径
- 每次处理的路径不重复、不疏漏
- 将路径分为不相干的两段,方便数据结构处理。
- 复杂度:O(nlogn + ∑ 单次处理关于重心答案)。
- 点分治讲解blog
二 . 点分树概述
- 定义:使结点x与所在部分树中的重心y连边,所得到的树形结构叫做点分树。
- 求点分树的方法就是在 divide(rt) 前加一句 add_edge(x,rt) 即可。
- 主要用处:让点分治实现修改操作。
- 复杂度:同点分治复杂度。
三 . 例题选讲
大部分点分治的唯一问题:如何计算经过重心x的合法路径条数。方法如下:
-
- 计算该部分树中每个结点到重心的距离及边权和,可通过一遍DFS实现。
- 计算两两路径配对所得的合法路径条数:将结点按长度排序,通过双指针l,r,满足长度L的限制,再使用树状数组查询边权≤w-dis[l]的点的个数,满足权值W的限制。
- 因为来自同一子树内的两条路径所拼得的路径不是简单路径,所以应减掉各子树的答案。
再套一个点分治模板,本题得解。
结:本题运用点分治的套路,体现了点分治综合性强的特点。
T2. [bzoj3730]震波
这个
来源:https://www.cnblogs.com/Leastle/p/12250045.html