专栏文章

题解:P8260 [CTS2022] 燃烧的呐球

P8260题解参与者 2已保存评论 2

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
2 条
当前快照
1 份
快照标识符
@minwlg6a
此快照首次捕获于
2025/12/02 09:32
3 个月前
此快照最后确认于
2025/12/02 09:32
3 个月前
查看原文

P8260 [CTS2022] 燃烧的呐球

前言:Rainbow_qwq 老师在讨论区声称有单 log\log 做法,但是并没有写题解,也并没有其他人写这个做法。 于是这是一篇时间复杂度做到 O(n+mlogn)O(n+m\log n) 的题解。做法完全参考了 Rainbow_qwq 老师的代码(也有一些是实在看不懂自己口胡的),除了一些小细节外是一致的。但是由于作者比较菜,证明不出更改了小细节的自己的做法,下面的叙述将与 Rainbow_qwq 老师的解法一致。
一句话题解:寻找可能在最小生成树中被用到的 O(mlogn)O(m\log n) 条边。
若无特殊说明,下文的“图”均指边带权的无向完全图。对于图 GG 以及 GG 的两个顶点 u,vu,v,记 G(u,v)G(u,v) 表示 (u,v)(u,v) 这条边的边权。

一个简单一些的问题

本文将基于这个问题的优秀解法进行优化。
给定一棵 nn 个点的树,点 uu 有权值 fu,guf_u,g_ufu,guO(n)f_u,g_u \le O(n))。构造图 GG,若 uuvv 的祖先则 G(u,v)=fu+gvG(u,v)=f_u+g_v,若 u,vu,v 不呈祖先后代关系则 G(u,v)=+G(u,v)=+\infty。求这张图的最小生成树。
时间复杂度要求:O(nα(n))O(n\alpha(n))
为方便叙述,我们不妨设所有 f,gf,g 互不相同。
解法:指定 11 号点为根,设点 uu 的父亲是 pup_u。对于每个不是根的点 uu,我们求出 uu 的祖先(包含自身)中 ff 最小的点 FuF_u,求出 uu 的子树(包含自身)中 gg 最小的点 GuG_u。取边 (u,Fpu),(pu,Gu),(Fpu,Gu)(u,F_{p_u}),(p_u,G_u),(F_{p_u},G_u)。我们声称,只需要把上述取出的 3n3n 条边拿出来跑 Kruskal 就能拿到原图的最小生成树。
由于边权在 O(n)O(n),Kruskal 中对边的排序可以使用桶排序在线性时间内完成,因此总复杂度是 O(nα(n))O(n\alpha(n)) 的。
正确性证明(感谢 UOJ 群中的 thomaswmy 老师提供帮助):
非常建议在看下面的文字的同时画图以便理解。
接下来将反复使用下面的事实:对于一条边 (u,v)(u,v),若存在一条路径使得路径上经过的所有边的权值都小于 (u,v)(u,v) 的权值,则 (u,v)(u,v) 必定不在最小生成树上。证明略。
对于一个不是根的点 uu,考虑 GuuG_u \ne u 的情况。此时,对于所有不等于 FpuF_{p_u}uu 的祖先(不包括 uu 自身)vv,可以使用 uFpuGuvu\to F_{p_u}\to G_u\to v 这条路径和前文的结论推导出 (u,v)(u,v) 这条边不属于最小生成树。
同样的,如果 FpupuF_{p_u}\ne {p_u},则对于 uu 子树内所有不等于 GuG_u 的点 vv 都有 (pu,v)(p_u,v) 不属于最小生成树。
现在考虑两个点 (u,v)(u,v) 满足 uuvv 的祖先,且 Fu=u,Gv=vF_u=u,G_v=v。设 xxuuvv 路径上第一个满足 FxuF_x\ne u 的点;设 yyvvuu 路径上第一个满足 GyvG_y\ne v 的点。那么,路径上没有点 zz 满足 Fz=u,Gz=vF_z=u,G_z=v 当且仅当 x,yx,y 均存在且 xxyy 的祖先。此时有 fx<fuf_x<f_uyy 子树中存在点 ww 满足 gw<gvg_w<g_v。考虑 uwxvu\to w\to x\to v 这条路径即可证明边 (u,v)(u,v) 不在最小生成树上。
至此,每一条边要么被选中,要么被证明不属于最小生成树。

接下来正式进入本题的题解。
大体思路:设原图为 GG。如果我们能找到若干张图 G1,,GkG_1,\cdots,G_k 使得 u,v,G(u,v)=mini=1kGi(u,v)\forall u,\forall v,G(u,v)=\min\limits_{i=1}^kG_i(u,v),并快速求出 G1,,GkG_1,\cdots,G_k 的最小生成树 T1,,TkT_1,\cdots,T_k,那么 T1TkT_1\cup\cdots\cup T_k 的最小生成树就是原图的最小生成树。
下面将逐步给出构造。
定义 siz(u)siz(u) 为为原树上 uu 的子树大小;
设原树上某边 (u,v)(u,v) 的长度为 siz(u)siz(v)|siz(u)-siz(v)|,以此定义 dist(u,v)dist(u,v) 为树上两点的距离;
定义 D1(a,b)=siz(a)+siz(b)D_1(a,b)=siz(a)+siz(b)
定义 D2(a,b)=dist(a,b)D_2(a,b)=dist(a,b)
定义 D3(a,b)={siz(a)siz(b),a,b互为祖先后代关系,+,otherwise.D_3(a,b)=\begin{cases}|siz(a)-siz(b)|,&a,b 互为祖先后代关系,\\+\infty,&\text{otherwise}.\end{cases}
容易发现 min(D1(a,b),D2(a,b))=min(D1(a,b),D3(a,b))=D(a,b)\min(D_1(a,b),D_2(a,b))=\min(D_1(a,b),D_3(a,b))=D(a,b)
(证明提示:当 a,ba,b 互为祖先后代关系时 D1=DD_1=D,否则 D2=D3=DD_2=D_3 =D
构造四张图 G1,G2,G3,G4G_1,G_2,G_3,G_4
G1((x1,y1),(x2,y2))=D1(x1,y1)+D1(x2,y2)G_1((x_1,y_1),(x_2,y_2))= D_1(x_1,y_1)+D_1(x_2,y_2)​;
G2((x1,y1),(x2,y2))=D3(x1,y1)+D1(x2,y2)G_2((x_1,y_1),(x_2,y_2))= D_3(x_1,y_1)+D_1(x_2,y_2)
G3((x1,y1),(x2,y2))=D1(x1,y1)+D3(x2,y2)G_3((x_1,y_1),(x_2,y_2))= D_1(x_1,y_1)+D_3(x_2,y_2)
G4((x1,y1),(x2,y2))=D2(x1,y1)+D3(x2,y2)G_4((x_1,y_1),(x_2,y_2))= D_2(x_1,y_1)+D_3(x_2,y_2)
根据上面关于 DD 的结论,应该能容易发现这四张图满足我们提出的限制(u,v,G(u,v)=mini=1kGi(u,v)\forall u,\forall v,G(u,v)=\min\limits_{i=1}^kG_i(u,v))。
接下来,逐个求解 G1,,4G_{1,\cdots,4} 的最小生成树。

G1G_1

最简单的部分。此时 G1((x1,y1),(x2,y2))=siz(x1)+siz(y1)+siz(x2)+siz(y2)G_1((x_1,y_1),(x_2,y_2))=siz(x_1)+siz(y_1)+siz(x_2)+siz(y_2),取 (x,y)(x,y)siz(x)+siz(y)siz(x)+siz(y) 最小的点,应该能容易发现其最小生成树是以 (x,y)(x,y) 这个点为中心的菊花。

G2G_2G3G_3

由于这两张图是对称的,下文将以 G3G_3 为例。
回顾一下,G3((x1,y1),(x2,y2))G_3((x_1,y_1),(x_2,y_2))y1,y2y_1,y_2 为祖先后代关系时权值为 siz(x1)+siz(x2)+siz(y1)siz(y2)siz(x_1)+siz(x_2)+|siz(y_1)-siz(y_2)|,否则为正无穷。
整理,设 f(x,y)=siz(x)+siz(y),g(x,y)=siz(x)siz(y)f(x,y)=siz(x)+siz(y),g(x,y)=siz(x)-siz(y)。此时,G2((x1,y1),(x2,y2))G_2((x_1,y_1),(x_2,y_2))y1y_1y2y_2 祖先时权值为 f(x1,y1)+g(x2,y2)f(x_1,y_1)+g(x_2,y_2)。可以简单化归到前文提到的问题。

G4G_4

回顾一下,在 y1y_1y2y_2 的祖先时,G4((x1,y1),(x2,y2))=dis(x1,x2)+siz(y1)siz(y2)G_4((x_1,y_1),(x_2,y_2))=dis(x_1,x_2)+siz(y_1)-siz(y_2)
xx 跑点分治。考虑某个重心 gg 周围的子问题,dis(x1,x2)dis(x_1,x_2) 可以写成 dis(x1,g)+dis(x2,g)dis(x_1,g)+dis(x_2,g)
和上面一样,设 f(x,y)=dis(x,g)+siz(y),g(x,y)=dis(x,g)siz(y)f(x,y)=dis(x,g)+siz(y),g(x,y)=dis(x,g)-siz(y) 即可化归到前文提到的问题。

于是最后把上面求出来的最小生成树拼起来跑 Kruskal 就好了,瓶颈在 G4G_4 中的点分治,复杂度是 O((n+m)logn)O((n+m)\log n)
注意我们其实并不需要在每次跑前文的简单问题是都跑 Kruskal,可以只把边选出来,最后再跑一次 Kruskal(否则复杂度上还要带 α(n)\alpha(n))。
如果要做到 O(n+mlogn)O(n+m\log n) 的话可以把有用的 2m2m 个点拉出来建一棵虚树。

评论

2 条评论,欢迎与作者交流。

正在加载评论...