1 条题解
-
0
问题分析
我们面对一个特殊的二维平面路径搜索问题:
- 建筑是垂直线段:从 到
- 天桥是水平线段:从 到
- 行人只能沿着建筑和天桥行走,不能在地面(y=0)行走
- 可以在交点处切换行走方向
- 目标:从建筑 的底部 到建筑 的底部 的最短路径长度
关键观察
1. 图的构建
这个问题可以抽象为一个图的最短路径问题:
- 节点:所有重要的交点,包括:
- 建筑底部点 (起点和终点所在)
- 建筑顶部点
- 天桥与建筑的交点 (当天桥经过建筑 时)
- 天桥与天桥的交点(当它们共享端点时)
- 边:沿建筑或天桥行走的线段
- 边权 = 线段长度(曼哈顿距离,因为路径是正交的)
2. 交点的性质
- 天桥 在高度 处与所有 的建筑相交
- 由于 坐标严格递增,天桥是水平的,建筑是垂直的,交点计算很简单:
- 建筑 与天桥 有交点当且仅当 且
- 交点坐标为
3. 图的规模控制
直接枚举所有交点会得到 的节点数,对于 不可行。需要优化:
- 对于每栋建筑 ,只考虑它实际相交的天桥
- 对于每座天桥 ,它相交的建筑是一个连续区间
算法思路
方法一:离散化 + Dijkstra(较直观)
步骤:
-
离散化所有高度
- 收集所有 、所有 和 0
- 排序去重,得到高度层级
-
构建分层图
- 每层对应一个高度
- 每栋建筑在它涉及的高度处都有节点
- 天桥作为水平连接同一高度的节点
-
添加边
- 垂直边:同一建筑在不同高度节点间,边权 = 高度差
- 水平边:同一高度上,相邻建筑通过天桥连接,边权 = 坐标差
-
运行最短路算法
- 从 到 的最短路径
- 使用 Dijkstra 算法
复杂度分析:
- 节点数: 级别(每栋建筑在相关高度有节点)
- 边数: 级别
- 时间复杂度:
方法二:事件扫描 + 最短路径(更高效)
核心思想:
将问题转化为一维区间覆盖问题:
-
预处理每栋建筑的"可达天桥"
- 对于建筑 ,找到所有 且 的天桥
- 这可以通过对天桥按 排序,使用数据结构维护当前活跃的天桥
-
构建邻接关系
- 垂直移动:在建筑 上,可以从高度 走到 ,代价
- 水平移动:在同一高度 ,如果多栋建筑都被同一天桥覆盖,它们之间可以水平移动
-
Dijkstra 优化
- 使用优先队列维护当前最小距离
- 同时更新垂直和水平移动
3. 特殊情况的处理
情况1:无路径
- 如果建筑 和 没有被任何天桥网络连通
- 输出 -1
情况2:直接路径
- 如果存在天桥同时覆盖 和 ,且高度足够低
- 路径 = (上下天桥)
实现细节
数据结构选择
- 存储建筑信息:数组存储 ,
- 存储天桥信息:按 排序,便于处理
- 邻接表:对于每个建筑,存储它所在的天桥及对应高度
- 并查集:可选,用于快速判断连通性
算法优化
- 懒惰更新:在 Dijkstra 中,不立即生成所有边,需要时再计算
- 区间查询:使用线段树或平衡树快速找到建筑 在高度 可以到达哪些天桥
- 双向搜索:从起点和终点同时进行 Dijkstra
样例分析
样例1
建筑: 天桥: 0: (0,8) 0: 0-1, y=1 1: (3,7) 1: 0-2, y=6 2: (5,9) 2: 0-6, y=8 3: (7,7) 3: 2-3, y=1 4: (10,6) 4: 2-6, y=7 5: (12,6) 5: 3-4, y=2 6: (14,9) 6: 4-6, y=5 起点:1,终点:5最短路径:
- 从建筑1底部(3,0)上升到天桥0的(3,1):代价1
- 沿天桥0到建筑0的(0,1):代价3
- 从(0,1)上升到天桥2的(0,8):代价7
- 沿天桥2到建筑6的(14,8):代价14
- 从(14,8)下降到建筑5底部?不行! 实际路径需要更多转换,最终长度27。
复杂度总结
- 时间复杂度:
- 空间复杂度:
- 关键难点:高效处理建筑与天桥的交点关系,避免 的显式建图
扩展思考
- 如果允许在地面行走,问题会简化为简单的 Manhattan 距离
- 如果天桥可以倾斜,问题变为更复杂的计算几何问题
- 实时查询多个 对,可以预处理全源最短路径或使用更高级的数据结构
这个问题的核心是将几何约束转化为图论问题,并利用数据的特殊结构(建筑垂直、天桥水平、x坐标有序)进行高效处理。
- 1
信息
- ID
- 5714
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者