1 条题解
-
0
题目重述
- 给定一棵 个节点的树。
- 有 个囚犯,第 个囚犯起点 ,终点 。
- 每个囚犯必须沿唯一最短路径从 到 。
- 每次只能移动一个囚犯到相邻房间,且目标房间不能有其他人。
- 问是否存在一种移动顺序,使得所有囚犯都能到达目的地。
核心难点
囚犯的路径在树上可能交叉或部分重叠,如果两个囚犯的路径有公共点(非同时作为起点/终点),则必须错开时间通过,否则会违反“房间只能有一个人”的规则。这种先后顺序会形成约束关系,若约束成环,则无解。
关键观察
1. 路径相交的类型
对于两个囚犯 和 :
-
在 的路径上
囚犯 要经过 ,必须等囚犯 离开 之后才能经过。
⇒ 约束: 必须在 之后经过 ,即 ( 依赖 先离开)。 -
在 的路径上
囚犯 要经过 ,必须在囚犯 到达 之前经过,否则 到达后 就有人了, 不能再进入。
⇒ 约束: 必须在 之后经过 ,即 ( 依赖 先离开)。 -
路径有公共边
这其实已经隐含在上面两种情况中,因为公共边的端点必然在两条路径上,会触发上述规则。
2. 依赖图模型
我们可以建立一个有向图 :
- 节点: 个囚犯。
- 边:根据上述两种规则添加有向边。
- 若 ,则加边 。
- 若 ,则加边 。
定理:原问题有解 ⇔ 该依赖图无环。
3. 为什么有环就无解?
假设存在环 。
- 表示 必须在 离开 之后才能经过 。
- 表示 必须在 离开 之后才能经过 。
- ...
- 表示 必须在 离开 之后才能经过 。
这样形成循环等待,无法安排谁先走,因此无解。
算法步骤
- 预处理树的 LCA,支持 判断一个点是否在一条路径上。
- 对每对囚犯 :
- 检查 是否在 的路径上,若是则加边 。
- 检查 是否在 的路径上,若是则加边 。
- 在 个点的有向图上检查环(拓扑排序 / DFS)。
- 无环输出
Yes
,有环输出No
。
复杂度与优化
- 朴素实现:,在 较大时不可行。
- 优化:
对每个囚犯 ,我们想知道路径 上是否有其他囚犯的 或 。
可以用树上差分 + DFS 序区间查询,把所有 标记在树上,然后对路径做查询,这样可降到 。
总结
这道题的关键是将移动冲突转化为有向图的依赖关系,并判断依赖图是否是有向无环图 (DAG)。
只要理解“起点在别人路径上”和“终点在别人路径上”产生的两种约束,就能建立模型,从而用图论方法解决。
- 1
信息
- ID
- 3158
- 时间
- 4000ms
- 内存
- 1024MiB
- 难度
- 9
- 标签
- 递交数
- 9
- 已通过
- 1
- 上传者