【ybt金牌导航1-3-5】【luogu P4381】岛屿 / Island
岛屿 / Island
题目链接:ybt金牌导航1-3-5 / luogu P4381
题目大意
有 n 个点 n 条边,边有边权,是双向的。
一条边只能走一次,一个点也只能经过一次。
如果两个点之间无法通过边连通,那你就可以选择渡船过,渡船之后它就相当于你走过的长度为 0 的边。
然后你可以自定起点,问你最多能走的距离。
思路
我们首先会发现是 n 个点 n 条边。
然后图其实就是由几个连通块组成,每个连通块都是有且只有一个环的情况。
那就是一个环,然后点可能会衍生出一些树。这种图其实就是叫做基环树。
那你根据题意,其实就是你要在每个基环树上找一条最长的路径(不能重复走),然后走完这一条就渡船到下一个基环树继续走。
而那个最长的路径就是基环树的直径。
那现在问题就变成了给你一个基环树,求它的直径。
那我们会想到这个直径有两种情况,要么经过环,要么不经过环。
那首先不经过环,那就只是在环上某个点衍生出来的树上找一条直径。
那可以想到用树形 DP 来解决,那就直接枚举环上每个点做一次就可以。
那如果经过环,那就要枚举两个点,然后它们到它们子树最远的位置和它们之间最远位置的和就是距离。
那你看到枚举两个点会超时,我们考虑弄出式子看如果优化。
首先它是环,你考虑破环为链。
然后你就会想到这么一个搞法,就是找到一个两个之间位置差距小于环大小的两个链上的点,然后让它的值最大。
点到它子树最远的距离 可以在第一种情况 DP 的时候算出,然后在环上的距离可以通过前缀和求出,因为你破了环,就相当于有两组距离小于环大小的点是表示这两组点的,然后距离就是从不同的方向,所以你在这两个间取了最大值就相当于用了环上距离远的那个。
(这里求距离你可以在链上搞一个前缀和 ,然后 间距离就是 )
那我们就是样让 最大,那把 的放在一起,让 最大,那我们枚举 ,那就是找 且 ,使得 最大。( 为环的大小)
你会发现它是可以单调队列优化的。
如果有一个点 ,有一个点 满足 ,那 就是没用的。
那就可以用这样的方法单调队列优化。
然后最后在这两种情况里面选一个最大值,就是这个基环树的贡献了。
把每个基环树的贡献加在一起,就是这个基环树森林的贡献,就是答案了。
代码
__EOF__

本文链接:https://www.cnblogs.com/Sakura-TJH/p/YBT_JPDH_1-3-5.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现