虚树学习笔记

虚树总结

算法简介

当树形 dp 只需要对于某些关键点求贡献时,对于整棵树 dfs 显得有点愚蠢,所以有了虚树——它是只保留关键点及其 lca 的重构树。

算法流程

用 st 维护右链,考虑现在要加入 \(now\)\(lc=lca(st_{top},now)\),分类讨论。

  1. \(lc=st_{top}\)也就是 \(now\)\(st_{top}\) 子树中:也就是在右链,此时只需入栈 \(now\)

  2. \(lc\)\(st_{top},st_{top-1}\cdots\) 的祖先:此时加入 \(now\) 会将 \(st_{top},st_{top-1}\cdots\) 顶替,所以将 \(st_{top},st_{top-1}\cdots\) 出栈 \(lc,now\) 入栈即可

  3. \(lc=st_{top-?}\):把 \(st_{top-?}\) 前的全出栈,\(now\) 入栈即可。

然后虚树就建好了。😝

[HEOI2014] 大工程

题目大意

原题晰。

题解

先建出虚树,考虑 \(\min/\max\) 显然是好求的,而设 \(sz_x\)\(x\) 子树中的关键点数量,\(dp_x\) 为这些关键点到它的距离和,\(w\)\(x\) 到它的儿子 \(v\) 的距离,推式子可得 \(x\)\(v\) 产生的贡献为:

\[(dp_x+sz_x*w)*sz_v+dp_v*sz_x \]

dfs 维护即可。

[SDOI2014] 寻宝游戏

题目大意

给定一颗带边权树,每次操作会添加/删除一个关键点,请在每次操作后输出最小的连接所有关键点的环。

题解

每次添加/删除关键点时根据它与 \(dfn\) 排序后的前驱后继的连边更新答案。

[SDOI2011] 消耗战

题目大意

给一棵树,有边权,求让所有指定点都与 \(1\) 号节点不联通的最小代价,多次询问。

题解

先建立虚树,然后预处理出 \(mn_{x}\)\(1\)\(x\) 路径上最小的边权,设 \(dp_x\) 为切断 \(x\) 子树中所有询问点与 \(1\) 联系的最小代价,显然有当 \(x\) 为询问点时 \(dp_x=mn_x\),否则 \(dp_x=\min(mn_x,\sum dp_v)\) 其中 \(v\)\(x\) 子树内。

[HNOI2014] 世界树

题目大意

一棵树指定 \(m\) 个关键点, 询问每个关键点所"统治"的结点数量. 一个点仅会被离其最近的关键点所"统治" ( 若距离相等, 则被标号最小的关键点"统治". )

题解

建出虚树考虑到虚树上的父子在原树上的路径就是链,链上的点必然是父子一人一半,然后没人要的子树就给根了。

[ZJOI2019] 语言

题目大意

原题晰。

题解

首先有与 \(x\) 能交易的点显然是构成了一颗生成树,于是问题转换为给定关键点求包含他们的最小生成树大小,然后就典中典了。

posted @ 2025-05-08 16:44  LEWISAK  阅读(40)  评论(3)    收藏  举报