1 条题解
-
0
「CCO 2024」Summer Driving 题解
题目分析
本题是一个在树结构上的博弈问题。Alice 和 Bob 轮流在树上移动,Alice 每次必须走恰好 条未走过的边,Bob 每次可以走最多 条边(可以重复走)。Alice 希望最终到达编号最大的城市,Bob 希望到达编号最小的城市。
关键观察
- 树结构性质:城市和道路构成一棵树,这简化了路径分析
- 移动规则差异:
- Alice 必须走恰好 条新边
- Bob 可以走最多 条边(可重复)
- 博弈目标相反:双方有完全相反的目标函数
算法思路
核心思想:二分答案 + 树形DP
我们使用二分答案来确定最终能够到达的城市编号。对于每个候选答案 ,我们判断在双方最优策略下,Alice 能否迫使游戏在编号 的城市结束。
主要数据结构
- 邻接表:存储树结构
- DFS序:用于子树区间操作
- 线段树:支持区间更新和单点查询
- 栈:维护DFS遍历路径
状态定义
dep[x]:节点 的深度f[x]:从节点 开始,在当前二分值 下 Alice 是否能获胜g[y]:辅助状态,处理特殊移动h[y]:记录边界条件mn0[x]:子树中满足条件的最小深度mnf0[x]:关键的最小深度值
算法流程
-
预处理:
dep[rt] = 1, dfs_pre(rt);通过DFS计算深度、DFS序,并建立父子关系
-
二分框架:
while (l < r) check(mid = l + r + 1 >> 1) ? l = mid : r = mid - 1; -
检查函数
check(mid):- 按深度从大到小处理节点
- 对于每个节点 :
- 计算
mn0[x]:子树中编号 的最小深度 - 处理特殊移动情况( 相关的移动)
- 更新线段树维护区间信息
- 计算博弈状态
f[x]
- 计算
-
关键判断:
- 如果
f[rt]为真,说明 Alice 可以到达编号 的城市 - 否则 Bob 可以阻止 Alice 到达这样的城市
- 如果
复杂度分析
- 时间复杂度:
- 二分答案:
- 每次检查:(DFS序 + 线段树操作)
- 空间复杂度:
代码亮点
- 高效预处理:使用DFS序将子树操作转化为区间操作
- 线段树优化:快速处理区间最小值查询和更新
- 状态压缩:通过巧妙的状态设计避免重复计算
- 分层处理:按深度分层处理,保证DP的正确性
总结
本题通过将博弈问题转化为树上的最优化问题,结合二分答案和树形DP,巧妙地解决了双方最优策略下的最终位置问题。算法充分利用了树结构的性质,通过DFS序和线段树优化了状态转移的效率。
- 1
信息
- ID
- 3790
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者