Kruskal 重构树学习笔记

Kruskal 重构树

回忆 \(\mathrm{Kruskal}\) 算法求最小生成树的过程,将所有边按边权排序,然后从小到大合并。若两个点不直接合并,而是新建一个虚点 \(z\),连 \(z \to x\)\(z \to y\),就形成了一棵 \(\mathrm{Kruskal}\) 重构树

\(\mathrm{Kruskal}\) 重构树有一些性质:

  1. 树为二叉树。
  2. 原图的所有结点为树的叶子结点。
  3. 若边按边权从小到大排序,则父结点点权 \(\ge\) 根结点点权;反之亦然。
  4. 结点 \(u\) 在原图中所有经过边权 \(\le d\) 的边能到达的点,就是它在按边权从小到大排序得到的重构树上最浅的,点权 \(\le d\) 的祖先 \(v\) 的子树内的所有叶子结点。

因此可以得出一个套路:如果题目有类似经过权值 \(\le d\)\(\ge d\) 的点或边的限制,就可以考虑使用 \(\mathrm{Kruskal}\) 重构树

若要处理经过点权 \(\le d\)\(\ge d\) 的点的限制,则需要为边赋值。例如,若限制经过点权 \(\le d\),则经过边 \(u \leftrightarrow v\) 需要满足 \(u,v\) 两个点的点权均 \(\le d\),因此边权为 \(\min(a_u,a_v)\)

有些题目既限制了权值 \(\min\) 也限制了权值 \(\max\),可以按边权从小到大和从大到小建两棵 \(\mathrm{Kruskal}\) 重构树,并根据 \(\min\)\(\max\) 倍增到相应的祖先结点,问题就转化成了两棵子树交。记 \(a,b\) 分别为两棵树的 \(\mathrm{dfs}\) 序,则问题为满足 \(i \in [l_1,r_1]\)\(j \in [l_2,r_2]\)\(a_i = b_j\)\(i,j\) 数量。设 \(c_i\)\(b_i\)\(a\) 中出现的下标,问题即求 \(c_i \in [l_1,r_1]\)\(i \in [l_2,r_2]\)\(i\) 的数量。二维偏序,可以在线主席树或者离线树状数组+扫描线求解。

参考:简单树论 by Alex_Wei

posted @ 2022-07-28 20:55  zltzlt  阅读(45)  评论(0)    收藏  举报