题意:

一个正方形中有n道竖直的墙,每道墙上开两个门。求从左边中点走到右边中点的最短距离。

分析:

以起点终点和每个门的两个端点建图,如果两个点可以直接相连(即不会被墙挡住),则权值为两点间的欧几里得距离。

然后求起点到终点的最短路即可。

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std; const int maxn = ;
const double INF = 1e4;
const double eps = 1e-; struct Point
{
double x, y;
Point(double x=, double y=):x(x), y(y) {}
}p[maxn * ]; typedef Point Vector; Point read_point()
{
double x, y;
scanf("%lf%lf", &x, &y);
return Point(x, y);
} Point operator - (const Point& A, const Point& B)
{ return Point(A.x-B.x, A.y-B.y); } Vector operator / (const Vector& A, double p)
{ return Vector(A.x/p, A.y/p); } double Dot(const Vector& A, const Vector& B)
{ return A.x*B.x + A.y*B.y; } double Length(const Vector& A)
{ return sqrt(Dot(A, A)); } struct Door
{
double x, y1, y2, y3, y4;
Door(double x=, double y1=, double y2=, double y3=, double y4=):x(x), y1(y1), y2(y2), y3(y3), y4(y4) {}
}; vector<Door> door; double d[maxn * ], w[maxn * ][maxn * ];
bool vis[maxn * ];
int cnt; bool isOK(int a, int b)
{//判断两点是否能直接到达
if(p[a].x >= p[b].x) swap(a, b);
for(int i = ; i < door.size(); ++i)
{
if(door[i].x <= p[a].x) continue;
if(door[i].x >= p[b].x) break;
double k = (p[b].y-p[a].y) / (p[b].x-p[a].x);
double y = p[a].y + k * (door[i].x - p[a].x);
if(!(y>=door[i].y1&&y<=door[i].y2 || y>=door[i].y3&&y<=door[i].y4)) return false;
}
return true;
} void Init()
{
for(int i = ; i < cnt; ++i)
for(int j = i; j < cnt; ++j)
if(i == j) w[i][j] = ;
else w[i][j] = w[j][i] = INF;
} int main()
{
//freopen("in.txt", "r", stdin); int n;
while(scanf("%d", &n) == && n + )
{
door.clear();
memset(vis, false, sizeof(vis));
memset(d, , sizeof(d)); p[] = Point(, );
cnt = ;
for(int i = ; i < n; ++i)
{
double x, y[];
scanf("%lf", &x);
for(int j = ; j < ; ++j) { scanf("%lf", &y[j]); p[cnt++] = Point(x, y[j]); }
door.push_back(Door(x, y[], y[], y[], y[]));
}
p[cnt++] = Point(, ); Init(); for(int i = ; i < cnt; ++i)
for(int j = i+; j < cnt; ++j)
{
double l = Length(Vector(p[i]-p[j]));
if(p[i].x == p[j].x) continue;
if(isOK(i, j))
w[i][j] = w[j][i] = l;
}
//Dijkstra
d[] = ;
for(int i = ; i < cnt; ++i) d[i] = INF;
for(int i = ; i < cnt; ++i)
{
int x;
double m = INF;
for(int y = ; y < cnt; ++y) if(!vis[y] && d[y] <= m) m = d[x=y];
vis[x] = ;
for(int y = ; y < cnt; ++y) d[y] = min(d[y], d[x] + w[x][y]);
} printf("%.2f\n", d[cnt-]);
} return ;
}

代码君

POJ (线段相交 最短路) The Doors的更多相关文章

  1. POJ_1556_The Doors_判断线段相交+最短路

    POJ_1556_The Doors_判断线段相交+最短路 Description You are to find the length of the shortest path through a ...

  2. 简单几何(线段相交+最短路) POJ 1556 The Doors

    题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...

  3. POJ 1556 The Doors(线段相交+最短路)

    题目: Description You are to find the length of the shortest path through a chamber containing obstruc ...

  4. POJ 2556 (判断线段相交 + 最短路)

    题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...

  5. POJ 1556 计算几何 判断线段相交 最短路

    题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...

  6. POJ 1556 The Doors【最短路+线段相交】

    思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...

  7. POJ 1556 The Doors(线段交+最短路)

    The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5210   Accepted: 2124 Descrip ...

  8. POJ 1556 The Doors(线段交+最短路)

    #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...

  9. poj 1066 线段相交

    链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Subm ...

随机推荐

  1. zhuan:点滴记录——Ubuntu 14.04中gedit打开文件出现中文乱码问题

    在中文支持配置还不完整的Ubuntu 14.04中,使用gedit打开带有中文字符的文件有时会出现乱码的情况,这是由于gedit对字符编码匹配不正确导致的,解决方法如下: 在终端中输入如下命令,然后重 ...

  2. Battle Over Cities (25)(DFS、连通图)

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

  3. HDU 4548 美素数

    Description 小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识.  问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为“ ...

  4. C#向C++编写的DLL传递字符串参数的办法

    使用StringBuilder,举例: C++代码中函数定义如下: PVPOWERFORCASTDLL_API int PVPowerForcast(SForcastInfo &_Forcas ...

  5. excle,aspose.cells 公式字段值取不到 xmls转xml

    问题: 一,单元格如果是公式的,读出值为0 aspose.cells 4.4.0.5版本 由于太低,读xmls后缀的excel文件时,发现如果此列是公式算出来的,值是获取不到的.获取到的值一直是0 二 ...

  6. 微信支付-b

    微信支付 APP端开发步骤(传送门):https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5 1.首先下载最新的微信支付的SDK包 ...

  7. poj 1659 Frogs' Neighborhood (DFS)

    http://poj.org/problem?id=1659 Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total S ...

  8. UIScrollView的坑--UINavigationController Push后位置变化

    今天在使用UIScrollView的时候遇到了一个问题,记录一下.如果这个记录有幸被您搜索到,或许对您有些帮助. 今天有这样一个需求: 在一个由导航条控制的页面中.需要显示一些信息,目前已经有10多行 ...

  9. 11个好用的jQuery拖拽拖放插件

    这次我们整理一些拖拽播放类型的jQuery插件,这些可能不是很常用,但偶尔会有网站设计项目用到,特别是后台相关的开发项目,这个拖放排序功能一般都会有,所以适合大家收藏起来,方便日后使用.接下来一起看盾 ...

  10. Windows下的Memcache安装与测试教程

    Windows下的Memcache安装 1.下载memcache for windows. 下载地址:http://splinedancer.com/memcached-win32/,推荐下载bina ...