用 进行状态转移
因为相互包含的长回文串与短回文串的中心一定是相同的,可以想到从短回文串同时向两侧扩充相同字符,递推得到更长回文串的状态。而要求的是任意点对中的最短路,很容易想到用 ,只不过进行最短路转移时需要注意满足回文串性质。
初始状态有两种:单个点()和单条边()。分别对应所有偶回文串与所有奇回文串的转移。这里要特别注意,一定要将所有 都初始化完以后,再初始化 ,这样能保证队列内 值为 的所有状态都在值为 之前,转移才是正确的。
这也是 与 求最短路之间的区别: 适用于无权图(即转移时的权重都一样,原理利用了队列先进先出的性质), 适用于有权图(优先队列维护最优状态,保证每次都从最优状态转移)。
本质在于二者都做到了从所有待转移状态中选择了最优状态进行转移,只不过 是基于 转移权重相同 和 队列先进先出的性质 实现的,而 是用 堆维护 实现的。
复杂度分析:总状态数 个,每个状态只会转移一次;每次转移时需要看的后继状态有 个,因此总复杂度 。
code
树形
设 :在以 为根的子树内,算上 上方的点对 的度数的影响,包含 且符合性质的最大子图( 不能为 )
考虑 : 的上方一定有一条边,所以若 ,则 的子树内只能留下 ;若 ,则只能留下 的其中三个儿子。根据状态定义,可得转移式为:
最大化 ,则取 的所有儿子中 数组的前三大即可。此时 的贡献为 (由于算上了 上方点对 度数的影响,因此 的父亲也要考虑到当前情况内)。
除此之外,也可以不考虑 上方边的影响,则只需要取 的所有儿子中 数组的前四大即可。这种情况的贡献单独计算,不计入状态转移内。
若 ,则 上方没有边,只需要考虑后一种情况。此时可以留下 的 其中一个分支 或者 其中四个分支(存在时)。
答案取上述所有情况的最大值即可。
code
首先显然只在起点和终点两个位置上下楼就可以得到最优解(证明略,不是此题重点)
自己想的暴力解法:bfs+优先队列,复杂度
code_bruce_force
解法1:整体二分(,复杂度是 的,如果最高高度小一点就可以过,但高度也是线性的,瓶颈在于每次二分一个高度都要初始化一次并查集。不知道怎么优化了qwq...)
code_binary_search
解法2:最大生成树 + (树链剖分+线段树) or (倍增lca)
此题与蓝桥杯14a的网络稳定性很像:最终每个询问都可以转化为求图中两点之间所有路径最小边权的最大值———等价于在原图的最大生成树上的两点间路径上边权的最小值。而最小值可以用倍增lca(不带修)或树链剖分+线段树(可带修)维护。具体细节见代码
code_倍增lca
code2_segtree
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话