P3206 城市建设 题解
Statement
动态边权的最小生成树。
Solution
法一:改边权相当于删一条边再加一条边. 考虑 LCT 维护最小生成树,加边好做,但删边比较麻烦,于是采用线段树分治,撤销一条边是好做的,cut 再 link 一下就行了. ,常数较大.
法二:两个结论:已知原图的一个边集 ,
-
把 所有边权设为 ,记此时原图的最小生成树的不属于 的边的集合为 ,接下来 每条边无论边权取何值,原图的最小生成树还包含 .
简洁证明: 边权的改变只会使 中被选上的边变少,而一条边被选入 当且仅当它连接了两个之前从未连通的连通块,容易发现 中的这些边的连接作用是即使 中的边也无法替代的,所以必须被选上.
-
把 所有边权设为 ,在原图中找出最小生成树,记不在树边上的非 边的集合为 ,接下来 每条边无论边权取何值,原图的最小生成树不包含 .
简洁证明: 边权变小只会让 加入的边变多,假如 中一条边加入,考虑 LCT 维护最小生成树的过程,被替换的一定是树边,也就是非树边一定不会反而成为树边.
考虑如何把两个结论用起来:
还是把修改看成一次加入和删除,发现按结论,加边可能可做,但删边是显然困难的;再考虑线性扫一遍处理询问的过程,发现一个询问前面的所有修改都已经应用,而它后面的所有修改还未应用;再往右扫一个,发现难点在于我们无法知道当前最小生成树形态。这启发我们按时间分治.
设当前处理的操作区间为 ,此时该区间内的边我们不确定,但其他边我们都确定了;说具体点就是 内的边权已被修改, 内的边权还未修改,但 内的修改将要处理,还不知道这些边的修改情况。这时假如我们往左走,右半部分就被确定;假如往右走,左半部分就被确定。现在的问题变成了求加入一些边后的最小生成树.
考虑上面两个结论:第一个告诉我们已确定的边中有一些是一定被选的,这样可以先把这些边组成的连通块缩点,算出边权和;第二个告诉我们可以删除一些无用的边. 假如我们在进入 时已经得到这样简化后的图,该区间的长度为 ,估计一下边和点的量级:
对于第一个操作,最多 个点不能被缩,此时 组成的边集形成 个连通块;故点数是 ;而第二个操作保证了边与点的量级同阶,故可以直接暴力加边 Kruskal,注意还要维护这个简化后的图,即还要缩点、删边.
缩点用可撤销并查集,删边随便记录一下,就做完了,注意递归到底时要把该操作进行了,即更改该边权值、输出答案.
然后做完了,若 Kruskal 为单 log,.
本文作者:Laijinyi
本文链接:https://www.cnblogs.com/laijinyi/p/18312417
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2023-07-19 My first blog