动态mst
动态mst是在可以加边的图中动态地维护这个图的最小生成树,例如下面的问题
给定一个图,每次会加入一条边,每次加入边后输出最小生成树的值
(或给出两个点x,y,输出最小化的联通两点需要边的最大值)
回忆 k r u s k a l kruskal kruskal 求最小生成树的过程,我们是将所有边按边权排序后,再一个个将边插入,维护当前的最小生成树,设当前插入的边连接 x , y x,y x,y 两点
- 若 x , y x,y x,y 未联通,直接加入
- 若 x , y x,y x,y 已联通,插入这条边后必然会形成一个环,且这条边一定是这个环中值最大的边,删去这个边更优,所以不加入
而动态维护最小生成树的操作原理也类似,假设当前插入边连接 x , y x,y x,y 两点,边权为 w w w
- 若 x , y x,y x,y 未联通,直接加入
- 若 x , y x,y x,y 已联通,插入这条边后必然会形成一个环,我们应该删掉这个环中权值最大的一条边
具体地说,我们在一直维护一颗树,每次进来一个边连接 x , y x,y x,y ,权值为 w w w
先看 x , y x,y x,y 是否联通,如果未联通,就将这条边加入维护的树;
如果已联通,先找到 x , y x,y x,y 路径上权最大的边 e m a x e_{max} emax ,值为 w m a x w_{max} wmax :
- 若 w m a x ≤ w w_{max}\leq w wmax≤w , 则新进来的边值是环中最大的,不插入
- 若 w m a x > w w_{max}> w wmax>w , 则先删除 e m a x e_{max} emax ,再将新进来的边加入
不难发现,只要保证先删边再加边就能保证我们一直在维护一个树(或者森林),我们需要在这颗树上删边和加边,还需要找到一条链上最大的边权 ,这样就可以想到用 l i n k _ c u t t r e e link\_cut\:tree link_cuttree 来维护这颗树
这里不会 l c t lct lct 的同学也可以继续看下去,当然先去看看 l c t lct lct 也没问题,这里稍微提一下:
l c t lct lct 是用 s p l a y splay spla