欢迎光临 ~|

Laijinyi

园龄:1年7个月粉丝:2关注:2

P3206 城市建设 题解

Statement

动态边权的最小生成树。n2104,m,q5104

Solution

法一:改边权相当于删一条边再加一条边. 考虑 LCT 维护最小生成树,加边好做,但删边比较麻烦,于是采用线段树分治,撤销一条边是好做的,cut 再 link 一下就行了. O(nlognlogq),常数较大.

法二:两个结论:已知原图的一个边集 S

  • S 所有边权设为 inf,记此时原图的最小生成树的不属于 S 的边的集合为 T,接下来 S 每条边无论边权取何值,原图的最小生成树还包含 T.

    简洁证明:S 边权的改变只会使 S 中被选上的边变少,而一条边被选入 T 当且仅当它连接了两个之前从未连通的连通块,容易发现 T 中的这些边的连接作用是即使 S 中的边也无法替代的,所以必须被选上.

  • S 所有边权设为 inf,在原图中找出最小生成树,记不在树边上的非 S 边的集合为 T,接下来 S 每条边无论边权取何值,原图的最小生成树不包含 T.

    简洁证明:S 边权变小只会让 S 加入的边变多,假如 S 中一条边加入,考虑 LCT 维护最小生成树的过程,被替换的一定是树边,也就是非树边一定不会反而成为树边.

考虑如何把两个结论用起来:

还是把修改看成一次加入和删除,发现按结论,加边可能可做,但删边是显然困难的;再考虑线性扫一遍处理询问的过程,发现一个询问前面的所有修改都已经应用,而它后面的所有修改还未应用;再往右扫一个,发现难点在于我们无法知道当前最小生成树形态。这启发我们按时间分治.

设当前处理的操作区间为 [l,r],此时该区间内的边我们不确定,但其他边我们都确定了;说具体点就是 [1..l1] 内的边权已被修改,[r+1,q] 内的边权还未修改,但 [l,r] 内的修改将要处理,还不知道这些边的修改情况。这时假如我们往左走,右半部分就被确定;假如往右走,左半部分就被确定。现在的问题变成了求加入一些边后的最小生成树.

考虑上面两个结论:第一个告诉我们已确定的边中有一些是一定被选的,这样可以先把这些边组成的连通块缩点,算出边权和;第二个告诉我们可以删除一些无用的边. 假如我们在进入 [l,r] 时已经得到这样简化后的图,该区间的长度为 len,估计一下边和点的量级:

对于第一个操作,最多 2len 个点不能被缩,此时 [l,r] 组成的边集形成 len 个连通块;故点数是 O(len);而第二个操作保证了边与点的量级同阶,故可以直接暴力加边 Kruskal,注意还要维护这个简化后的图,即还要缩点、删边.

缩点用可撤销并查集,删边随便记录一下,就做完了,注意递归到底时要把该操作进行了,即更改该边权值、输出答案.

然后做完了,若 Kruskal 为单 log,T(n)=2T(n2)+O(nlogn)=O(nlog2n).

本文作者:Laijinyi

本文链接:https://www.cnblogs.com/laijinyi/p/18312417

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Laijinyi  阅读(19)  评论(0编辑  收藏  举报
历史上的今天:
2023-07-19 My first blog
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起