这道题我贡献了一个 WA, 原因第一个是我的 sgn 函数写错了,第二个是没有初始化一个变量,还好后来发现了。这道题思路上是没有错误的。

这题的计算几何方面的算法是很基础的,图论涉及到了最短路,也算是很基础的。

原题地址:http://poj.org/problem?id=1556

测试数据:http://mcpc.cigas.net/archives.html , 选择 Mid-Centrail USA 1996 相关的项来下载即可在压缩包中找到。

POJ 1556 门

题目描述

你需要找到一条通过一个有墙阻碍的房间的最短路。这个房间的四条边始终在 x = 0, x = 10, y = 0 和 y = 10 上。起点和终点始终在 (0, 5) 和 (10, 5) 上。墙的数量的范围是 0 ~ 18, 每堵墙上有两个门。下图展示了一个这样的房间,并且标出了从起点到终点的最短路。

房间示意图

输入数据

上图房间的输入数据如下:

2
4 2 7 8 9
7 3 4.5 6 7

第一行包含一个数字,表示墙的个数。接下来每行描述一堵墙,共 5 个数字。第一个数字是该墙的 x 坐标 (0 < x < 10), 剩下的 4 个数字是这堵墙的门的 4 个端点的 y 坐标。墙的 x 坐标会以升序给出,且每堵墙的门的端点 y 坐标也以升序给出。输入文件至少会包含一组数据。如果读到墙的数目是 -1, 那么说明输入数据结束。

输出数据

对于每组输入数据,输出一行。每行输出的数据是从起点到终点的最短路,四舍五入保留两位小数。不能有多余空格。

样例输入

1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1

样例输出

10.00
10.06

解题思路

把门的每个端点存在一个点集 G 里,把墙的阻碍部分的线段存在一个线段集合 S 里。为了方便,点集中可以再增加两个点,起点和终点。然后,以点集中的点为顶点,构建一个图,图中每两个顶点的边权值先赋值为 +∞. 然后两两枚举顶点,设当前枚举到的顶点是 u, v, 判断这两个点确定的线段 (u ~ v) 与线段集合 S 中的任何线段是否相交,如果 (u ~ v) 与 S 中没有任何线段相交,那么就可以赋其边权值 (u, v) 为线段 (u ~ v) 的长度。之后在图 G 上求起点到终点的最短路。

源代码

原创文章,转载请注明来源:http://euyuil.com/2603/poj-1556-the-doors/