一个mst算法。
其用于求解一些特殊的mst问题。
例题1:CF888F
我们要求一个集合到外面的最小边。
对于每个集合维护一个trie表示这个集合内的所有数。
维护一个整体trie,表示所有数。
对于每个集合,枚举这个集合的所有点。然后询问整体trie减去这个集合trie的最小异或和即可。
时间复杂度(O(nlog_2^2n))
当然还有一个做法:考虑按位分治。把高位为(1,0)的都递归下去,然后询问两个集合的最小异或和。
例题2:at3611
考虑直接套用boruvka算法。
考虑树上dp。
每个点要记录最大值,与最大值颜色不同的次大值。
然后这样子就能求出和一个点距离最近的点。
然后就能用boruvka了。
另一个做法:把所有边集做若干次mst,排除一定不会选择的边。
然后全局做一个mst,答案不变。
考虑点分,考虑跨越重心的路径。
设(d_x)表示(x)点到重心的距离。
则我们两个点(x,y)的点权可以被表示成(d_x+a_x+d_y+a_y)
令(p_x=d_x+a_x),则连接两个点(x,y)的代价可以被表示成(p_x+p_y)
容易发现只要我们求出(p_x)的最小值位置(y),把所有点和(y)连边。
这样子就把跨过分治中心的路径的mst求出来了。
然后最后做一次mst即可。
例题3:病毒实验
其实这道题不是boruvka。但是运用了这个算法的思想。
考虑我们怎么判定一个点是否能被拓展。预处理出(f_s)表示有(s)集合内的方向,最长连续段的长度。
可以在常数时间*(O(n))内预处理。
考虑把矩阵划分成若干个连通块,每个连通块内有一关键点(c)。从连通块任意点都能拓展到(c)。
一个显然的性质:如果一个连通块关键点(b)能够走到(c),那么(b)所在连通块不能用于更新答案。
考虑使用这个性质进行bfs。可惜对时间复杂度没有改进。
考虑boruvka算法的时间复杂度证明。
每次给一个连通块通过bfs找到其不在连通块的出边。
然后把它和这个出边所指向的连通块合并。
如果bfs到一个已经被合并的区域就跳出,不用bfs了
可以发现时间复杂度是(O(RClog_2 RC))
会发现一个点到的合并只有两种:
1.和一个区域合并。
2.bfs到一个被合并过的区域。
会发现1情况使两个连通块变成一个,2情况使一个连通块变成(0)个。
所以时间复杂度有保证。
例题4:lg6199
考虑在(T2)上进行树分治。
设(d_x)表示(x)到重心的距离。
连接两个点的代价就是(d_x+d_y+T1dis(x,y))
建立连通块在(T1)上的虚树,就转化成例题2了
例题5:https://www.cnblogs.com/ctmlpfs/p/14333369.html