Kruskal 重构树 学习笔记

算法介绍

Kruskal 重构树就是在 Kruskal 算法过程中重新建出了一棵树,这棵树具有一些优美的性质可以解决一类问题,下面就详细叙述一下:

首先复习一下什么是 Kruskal 算法,本质上来说这是一种贪心算法,用于解决最小生成树的问题,把所有边权由小到大排序,用并查集维护连通性,若当前边 ( u , v ) (u,v) (u,v) 不联通,就把当前边加入到最小生成树中。

下面说说什么是 Kruskal 重构树,在 krusakl 算法过程中,每当一条边 ( u , v ) (u,v) (u,v) 被加入最小生成树,令 g u = r o o t ( u ) gu=root(u) gu=root(u) g v = r o o t ( v ) gv=root(v) gv=root(v),我们新建一个虚拟节点作为 g u , g v gu,gv gu,gv 的父亲。这样的过程结束后,我们得到一棵树,这就是 Kruskal 生成树。

它有什么性质呢?

  • 最显然的,原图的所有节点都是叶子节点。
  • 这棵树是一个二叉树

但这并不是重点,如果我们在合并时把虚拟的父亲节点的点权设为当前边的权,我们就能真正发现其美妙之处:

  • 这是一个大根堆
  • 最重要的,也是最好用的性质,就是对于原节点 u , v u,v u,v 来说,其所有路径上最小的最大值就是重构树上 l c a ( u , v ) lca(u,v) lca(u,v) 的点权。

另外,我们可以知道,如果我们用 Kruskal 求最大生成树的话, l c a ( u , v ) lca(u,v) lca(u,v) 的点权是其所有路径上最大的最小值

这个东西,不得不说实在是太强了…

下面在我们开始我们的思维旅程之前,来道小练习热热身(误)。

[IOI2018]狼人

题意简述:你有两个形态,人形和狼形,现在有一张 n n n 个点, m m m 条边的无向图,有 q q q 次询问,每次给定 l i , r i , s i , t i l_i,r_i,s_i,t_i li,ri,si,ti,一开始你在 s i s_i si 并且处于人形,当你处于人形时不能经过 [ 1 , l i − 1 ] [1,l_i-1] [1,li1],处于狼形不能经过 [ r i + 1 , n ] [r_i+1,n] [ri+1,n],你必须也只能在 [ l i , r i ] [l_i,r_i] [li,ri] 间变身一次,即从人形转为狼形,问是否存在一种合法的方案从 s i s_i si t i t_i ti

题目分析:思考一下,发现我们肯定是这样一种走法:先走到 [ u i , v i ] [u_i,v_i] [ui,vi] 间一个点变身,然后走到 t i t_i ti。假定我们确定了在 e e e 中转,会有什么要求呢?

  • 存在一条 s s s e e e 的路径,路径上最小的点编号不小于 l i l_i li
  • 存在一条 e e e t t t 的路径,路径上最大的点编号不大于 r i r_i ri

这长的就很 Kruskal 重构树。第一个等于是最小值最大,第二个等于是最大值最小,可以分别拿最小生成树和最大生成树搞搞,唯一的问题是这题是点权,可以点权下放到边权,但是要注意最小生成树是取 max ⁡ \max max,最大生成树是取 min ⁡ \min min

但是我们只是假设了一波,并不太能做,再考虑一下,此时暴力怎么做?枚举 [ l i , r i ] [l_i,r_i] [li,ri] 分别和 s i s_i si t i t_i ti 去跳 LCA,看是否有符合两个要求的点,这启示我们,如果对两棵重构树 dfs 出 dfs 序,我们是可以提前倍增在重构树上找出每个 s i s_i si, t i t_i ti 最后一个满足约束的祖先 a i , b i a_i,b_i ai,bi,那么显然只有 dfs 序在 [ d f n a i , l o w a i ] , [ d f n b i , l o w b i ] [dfn_{a_i},low_{a_i}],[dfn_{b_i},low_{b_i}] [dfnai,lowai],[dfnbi,lowbi] 中的点可以成为中转点,有人可能问了,不是要满足 [ l i , r i ] [l_i,r_i] [li,ri] 中吗?仔细思考,如果满足前两个约束,显然肯定满足这个约束,那么我们把这玩意抽象到一个二维平面上,一拍脑门,发现这是个二维数点的经典问题,又由于nkoj不支持交互这题可以离线我不想写可持久化线段树,把询问离线下来,树状数组随便搞搞就好了。。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值