【题目】IOI2018 狼人

本文探讨了在大规模无向图中,通过Kruskal重构树和二维数点技巧,解决从任意点出发,经过特定区间内某点,最终到达另一点的问题。此方法适用于寻找最优路径,并确保路径上点的编号满足给定条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

给出一张NNN个点MMM条边的无向图,保证图连通。你有QQQ个行程,第iii个行程的起点是SiS_iSi,终点是EiE_iEi。在每个行程开始时你必须是人形,在每个行程结束时你必须是狼形,且途中只能在[Li,Ri][L_i,R_i][Li,Ri]内的某个点变身。问每次行程能否完成。

N⩽200000N\leqslant 200000N200000M⩽400000M\leqslant 400000M400000Q⩽200000Q\leqslant 200000Q200000


思路

前置芝士:Kruskal重构树二维数点

每个可行的行程可以表示成:Si→X→EiS_i\rightarrow X\rightarrow E_iSiXEi,其中Li⩽X⩽RiL_i\leqslant X\leqslant R_iLiXRi

X→EiX\rightarrow E_iXEi这一部分路径为例。这条路径可以等价成Ei→XE_i\rightarrow XEiX。我们需要找出从EiE_iEi出发,经过的点的编号最大不超过RiR_iRi,能够到达的所有点,这些点都有可能成为XXX。路径上的最大点权尽可能小,假装容易想到最小生成树。但是生成树处理的是边权,这里要把点权转到边权:经过一条边时,一定会经过这条边的两个端点,因此可以把边权设为两个端点编号的最大值。然后建一棵传说中的Kruskal重构树。为了后面讨论方便,叶子结点的点权设为本身的编号。于是原图中两点路径上的最大点权的最小值就是树中两点的LCA的点权。并且,由于连通块是按权值从小到大合并的,树中非根节点的点权一定不会超过父亲的点权。

在重构树中找到点SiS_iSi,倍增找到其祖先中深度最浅、点权不超过RiR_iRi的点,则点XXX必须在以该点为根的子树内。

同理,需要找出从SiS_iSi出发,经过的点的编号最小不低于LiL_iLi,能够到达的所有的点:边权取两个端点的点权的最小值,求最大生成树,在重构树上倍增,找到深度最浅、点权不低于LiL_iLi的点,则点XXX必须在以该点为根的子树内。

于是点XXX在两棵重构树上的DFS序各有一个范围,以每个点分别在两棵树上的DFS序为横纵坐标,转换成二维数点问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值