虚树-树上动态规划的利器

虚树


问题引入

在一类树上动态规划问题中,题目给出的询问往往包含树上的很多各节点,并保证总的点数规模小于某个值.

如果我们直接在整颗树上进行dpdp的话,时间复杂度与询问的次数有关,这显然是不可接受的,如果我们可以找到一种动态规划的方法,使其时间复杂度与询问中点的实际规模相关就好了.

于是虚树应运而生.

虚树概念

虚树即是一颗虚拟构建的一棵树,这个树只包含关键点以及关键lcalca的点,而其他不影响虚树结构的点和边都相当于进行了路径压缩,整颗虚树的规模不会超过关键点数目的两倍.

举个栗子

原树

这里写图片描述


虚树

包含关键点 1 2 3的虚树

这里写图片描述

包含关键点 1 3 7 8 的虚树

这里写图片描述

其中6是关键lcalca节点

很显然,其他不是那么关键的点及边形成的路径我们都将他们压缩到了一条边,例如在第二个虚树中,我们相当于把161−6的路劲压缩到了边161−6中,而99号节点这种非关键点我们直接扔掉了,因为我们在 d p 的时候不会用到99号点.

虚树构建

预处理我们对整颗树得到dfs序列(即前序遍历),记为 d f n [ u ] .

我们使用一个,从栈顶到栈底的元素形成虚树的一颗树链.

当我们得到一些询问点(关键点)的时候,对这些点按照他们的dfn[u]dfn[u]值进行排序,然后从dfndfn值小的开始扫描,结合栈中保存的树链信息就可以将这颗虚树构建出来.

假设我们当前扫到的关键点为

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值