一道关于删边的贪心问题
感觉自己想的时候很简单,不知道为什么其他人都没这么想,老师的正解也比较奇怪
# 题面
> LOJ
# 解析
- 一个联想
看到这样一种“只删边不加边,而且在当某一些边都被删除的时候会对答案造成影响”的题,我首先联想到的是 LCT 维护一般图连通性的问题:
给出一个无向图,进行删边加边操作,询问两点是否连通。
(因为是 LCT,也可以有加边 awa)我们考虑用 LCT 做。LCT 维护的是一棵树,但是这是一个图,可能有环。我们只能用 LCT 维护图上的一些边,使得图的连通性不变(其实就是维护图的一个生成森林)。
怎么做呢?可以离线 !先处理出每条加入的边被删除的时间。
然后我们就在 LCT 上删边加边——
- 加边 $(u,v)$:如果 $u,v$ 本身不连通,直接加边;如果 $u,v$ 连通,那么加入 $(u,v)$ 后会形成环,于是我们找到形成的环上最早被删除的一条边,然后把它删掉,很像生成树算法中的破圈法。
- 删边:如果这条边在 LCT 里就删掉,不然就不管他。
为什么正确呢?考虑我们删去 LCT 上一条边 $(u,v)$ 的时候,在 LCT 上 $u,v$ 就不连通了,此时在图上一定也不连通——因为 LCT 维护了两点之间存在时间最长的一条路径,如果这条路径都断了,那其他路径也已经断了。
- 回到最短路
那么把 LCT 维护存在时间最长的路径的思想运用到这道题,其实就是维护每个节点 $u$ 到节点 $1$ 的存在时间最长的一条最短路。
那就很方便了——原本最短路 Dijkstra 只需要存 dis[u]
表示 $u$ 到 $1$ 的最短路,现在再加上一个 tim[u]
表示 $u$ 到 $1$ 的最短路中最晚被删除的一条是什么时候被删除(就是存在时间最长)。转移的时候以 dis[u]
为第一关键字,tim[u]
为第二关键字。
复杂度 $O(n\log n)$,离线。
要在线的话也可以 :) 不就是写个 LCT 嘛(算了)
# 源代码
1 | /*Lucky_Glass*/ |