POJ (线段相交 最短路) The Doors
题意:

一个正方形中有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的更多相关文章
- POJ_1556_The Doors_判断线段相交+最短路
POJ_1556_The Doors_判断线段相交+最短路 Description You are to find the length of the shortest path through a ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
- POJ 1556 The Doors(线段相交+最短路)
题目: Description You are to find the length of the shortest path through a chamber containing obstruc ...
- POJ 2556 (判断线段相交 + 最短路)
题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...
- POJ 1556 计算几何 判断线段相交 最短路
题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...
- POJ 1556 The Doors【最短路+线段相交】
思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...
- POJ 1556 The Doors(线段交+最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5210 Accepted: 2124 Descrip ...
- POJ 1556 The Doors(线段交+最短路)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- poj 1066 线段相交
链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS Memory Limit: 10000K Total Subm ...
随机推荐
- 各种语言简单的输出Hello World
PHP echo 'Hello World'; Java System.out.println("Hello World"); Shell_(BashShell) echo Hel ...
- RFC822DateGMT
function RFC822DateGMT(dd: TDateTime): string; const Days:..] of string= ('Sun','Mon','Tue','Wed','T ...
- Python学习_从文件读取数据和保存数据
运用Python中的内置函数open()与文件进行交互 在HeadFirstPython网站中下载所有文件,解压后以chapter 3中的“sketch.txt”为例: 新建IDLE会话,首先导入os ...
- The Best Rank (25)(排名算法)
To evaluate the performance of our first year CS majored students, we consider their grades of three ...
- envi中多波段图层叠加layer stacking
Basic Tools——layer stacking 选择投影和输出的文件 波段1-7波段图层都叠加在一个文件中了
- Linux内核树的建立-基于ubuntu系统
刚看 O'REILLY 写的<LINUX 设备驱动程序>时.作者一再强调在编写驱动程序时必须 建立内核树.先前的内核只需要有一套内核头文件就够了,但因为2.6的内核模块吆喝内核源码树中的目 ...
- 视网膜New iPad与普通分辨率iPad页面的兼容处理
一.这是篇经验分享 就算不是果粉也应该知道,iPad2与new iPad的重大区别之一就是显示屏的分辨率.new iPad显示屏被称之为“视网膜显示屏”,其设备分辨比(之前有详细介绍,点击这里查看)是 ...
- 汽车之家, 比亚迪等成为开源数据库SSDB的用户
开源的 NoSQL 数据库 SSDB 已经一岁多了! 在这一年中, SSDB 不断被应用在众多业界知名互联网企业, 创业团队的产品中. 最近, 比亚迪汽车也成为 SSDB 的用户, 其将 SSDB 作 ...
- js 判断页面加载状态
//----判断当前页面是否加载状态 开始 ---- document.onreadystatechange = subSomething;//当页面加载状态改变的时候执行这个方法. function ...
- setTimeOut传参数(转)
无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数.带参数则立马执行,没有延时效果.可通过下面方式实现. <script ...