圆方树
前言
-
不知道会不会考(好像在 NOI 大纲没有看到?),但是很有意思的一个结构
-
广义圆方树可以解决一切问题,
所以不需要圆方树 -
其实很久前写过一次总结,然而当时的所有稿子都被清了,现在因为某种原因再写一次,大概直接从题目入手吧
构造 && 性质
-
对于每一个点双新建一个方点表示这个点双,对于点双内的点看成圆点,向方点连边
-
注意到两个点也算一个点双,所以可以发现圆点之间相隔方点,方点之间相隔圆点
-
两个点之间的必经点集就是对应的圆点在圆方树上路径上的圆点点集
-
两条边之间的必经点集就是所在方点之间的圆点集合
例题
-
先将广义圆方树建出来,对于一个方点的父亲我们强制为这个点双 dfn 序最小的节点
-
对于每个圆点到方点之间的连边我们设为到这个方点的父亲的圆点的最小距离,同时顺便求出每个点以同一个方向到根的一个距离和这个环的距离和
-
那么对于两个圆点之间的最短路分类讨论:
- 如果 \(\operatorname{lca}\) 为圆点,那么最短距离就是两个圆点在树上的距离
- 否则的话,求出两个圆点对应在这个方点下的祖先节点 \(A,B\) ,那么答案就是两个圆点分别到各自祖先的距离加上 \(mindis(A,B)\)
- 两个圆点的最短距离可以利用我们之前球的两个点同一方向到根的距离和环的总长取求
-
细节较多
接下来是三道必经点/边相关的板题
UVA1464 Traffic Real Time Query System
-
可以发现两个点之间可能经过的点就是对应圆点在树上路径中所有方点代表的点集合
-
那么对于每个方点维护点双中的最小值,但是可能被菊花图卡了
-
那么方点只维护自己的子节点的最小值
-
对于方点维护一个
set
,用树剖动态维护这一过程即可
-
答案就是包含所有关键点的最小连通块的大小减去关键点的个数
-
具体的如果将关键点抽取出来构成一个虚树,那么这个连通块的缩小版就是这个虚树
-
怎么求这样的连通块的点的权值和,我们考虑将点的权值放在边上,按照点的 dfs 序排序,对于相邻的两个点之间求路径和在加上第一个点到最后一个点的路径和,最后将总和/2 就是我们需要的总和了
P4630 [APIO2018] Duathlon 铁人两项
- 将方点的权值设为点双中的点的个数,将圆点的权值设为 -1 ,那么两个点之间 \(c\) 的选择的个数就是两个点之间的路径和,简单 \(dp\) 一下就可以了
-
就是从 1 找到一条路距离最长
-
考虑还是先把圆方树建出来,对于方点求出所在环的根通过这个环最后回来/不回来的最长路径,对于圆点就求这个圆点通过子树的点最终回来/不回来的最长路径
-
显然圆点可以直接通过方点转移,对于方点最理想的是按照环的 dfn 序一次扫一遍,同时需要预处理出每个点到环中的根的距离和环的总长
-
对于两个点的点双需要特殊处理一下
SP2878 KNIGHTS - Knights of the Round Table
-
虽然和圆方树本身没什么关系,但是和点双有点关系
-
结论一:一个点双中如果有一个奇环,那么所有点都被至少一个奇环包含
-
结论二:一个点双如果没有奇环,那么就是一个二分图
-
所以求出所有点双后判断是否是二分图就可以了