[Luogu2495] [SDOI2011] 消耗战 [树形dp][LCA][虚树]

[ L i n k \frak{Link} Link]


题意:有一棵n个点,n-1条边的树。
m个询问。每次询问使给出的k个点与1号点不连通要删除的边的最小权值和。


建模跑最小割
Σki不小,可能要预处理。
考虑让某个点和一号点不连通要删除的最小边权,发现是这个点到一号点路上最小的边权。
然而现在要求的是多个点不连通,求单个点是没用的;
能不能用单个点的答案快速推出多点答案?

预处理单点答案是可以做到的。
能不能推上多点?
比如说一个子树里面只有一个点要被断掉,现在向上推,假如新推到的结点也是要被断开的,
那么这个子树的答案就是preroot
——假如不是这样,而是多个子树合并呢?
fx = min{ Σfson, prex }
因为假如选了prex那就一定不会选fson
也不会出现多个fson合并的情况,因为这时候才处理到意味着它们合并的话,断边在x子树外。

然而虽然yy了这么多,但是如果每次都遍历合并,复杂度是Θ(mn),不可行。
需要考虑更加优秀的方法。
过程中隐约地有那种往上跳的感觉。
会不会可以倍增?

合并点一定是它们的lca.是不是可以倍增lca
猜想最终复杂度大约是 Θ(mlogn)


怎么做?
既然要倍增,那么现在考虑的就不是整棵树了。倍增是针对询问里面提到的点的。
复杂度Θ(Σkilogn)

那么,每次把询问点单独考虑。
合并的过程只需要考虑到关键点和lca
那么可以按dfs序排序关键点,把关键点和lca提出来,建树。
ps. tarjan/rmqlca也没有问题。


建出来的这棵树就是虚树。
虚树的套路大约就是Σki还可以接受
然后把要用到的那一部分每次提出来单独建树跑奇奇怪怪的东西
模板题见世界树。


什么 我居然口头阿过这道题题
其实挺 naive 的。。。不管是 dp 还是倍增优化都是简单的思路
不如跳舞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值