[NOI2018] 归程,Kruskal 重构树
2022/1/27 23:34:27
本文主要是介绍[NOI2018] 归程,Kruskal 重构树,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
给出一张点数为 \(n\),边数为 \(m\) 的无向连通图,每个边 \(e\) 的属性是一个二元组 \((l,a)\)。
接下来给出 \(q\) 次询问,每次给出一个出发点 \(v\) 以及约束 \(p\),求出从 \(v\) 至 \(1\) 号节点的最小花费。
花费的计算是这样的:将 \(p(v,1)\) 分为两段 \(p(v,u)\),\(p(u,1)\)。
\(p(v,u)\) 满足所有的经过边 \(e\in p(v,u)\) 都有 \(a_e > p\),这段路径是免费的。
从第一次经过 \(a_e\leq p\) 的边开始,这一段路径为 \(p(u,1)\),这段路径的花费是 \(\sum_{e\in p(u,1)}l_e\)。
假若询问离线,我们可以考虑将询问按照 \(p\) 从大到小排序,然后将图中的边按照 \(a\) 排序,开始是一个仅有点没有边的图,然后逐渐按顺序向其中加边,当当前询问的约束为 \(p\) 时,将所有 \(a>p\) 的边加入其中。
那么这个过程中整个图就会形成若干个连通块,假若当前起点 \(v\) 属于某个连通块 \(B\),那么任何以 \(u\in B\) 为起点的答案都是一样的。因为任意边 \(e\in B\) 都有 \(a_e>p\),是属于第一种路径,所以这部分路径是对答案没有贡献的。
于是我们考虑先预处理出所有点至 \(1\) 号节点的 \(l\) 值的最短路,这个可以直接以 \(1\) 号节点为起点跑一遍 Dijkstra(关于 SPFA,,,
然后关于连通块我们就可以直接用并查集维护,按照最短路的值合并。具体地说,就是以最短路值小的节点作为根,于是当我们处理询问时只需 find 一下根,再输出其最短路值即可。
离线的好处是,由于我们已经对询问排序,加入的边不会再被去掉,这样就可以直接用并查集维护了。时间复杂度 \(O( m\log n+q\log n)\)。
这篇关于[NOI2018] 归程,Kruskal 重构树的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南