【题解】CF1550F Jumping Around 最小生成树、boruvka 算法
一个直接的想法是,对于每个询问 \(k\) 建出无向图 \(G_k=(V,E_k)\) ,\((u,v)\in E_k \Leftrightarrow d-k\le |a_u-a_v|\le d+k\) 。
可以发现,若 \((u,v)\in E_k\) ,那么一定有 \((u,v)\in E_t,t\ge k\) 。
可以类似 P7516 [省选联考 2021 A/B 卷] 图函数 中的思想,将每条边建出来边权为最小的满足 \(d-k\le |a_u-a_v|\le d+k\) 的 \(k\) ,不难看出 \(k=|d-|a_u-a_v||\) 。
那么每对询问相当于询问 \(s,x\) 在图 \(G_k\) 中是否连通。
点 \(s,x\) 在图 \(G_k\) 中连通,当且仅当存在一条 \(s,x\) 之间的路径满足路径上最大的边权小于等于 \(k\) 。
无向图路径最大边权最小对应着最小生成树上上两点的距离,因此只要建出最小生成树处理出点 \(s\) 到每个点的距离即可 \(O(1)\) 处理询问。
而对于边数 \(O(n^2)\) 条,且 \(n = 10^5\) 级别的最小生成树问题, kruskal 和 prim 算法全都寄了。
这里使用 boruvka 算法,每次连通块个数减半,用 std::set
维护点集,复杂度 \(O(n\log^2n)\) 。
题目思想:
-
类似“半动态传递闭包”,利用单调性将边的边权设置为最小的存在该条边的“版本”,把连通性 / 可达性问题转化成最优性问题(该问题本质上对应着动态加边的图连通性问题)。
-
boruvka 算法利用题目性质处理边数 \(O(n^2)\) 条,且 \(n = 10^5\) 级别的最小生成树问题。