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 ...
随机推荐
- 【转】How to view word document in WPF application
How to view word document in WPF application (CSVSTOViewWordInWPF) Introduction The Sample demonstra ...
- bootstrap IE兼容
<meta name="viewport" content="width=device-width, initial-scale=1"> & ...
- javascript event兼容IE和FF
事件对象在IE和FF下的兼容写法 function abc(event){ var e=event||window.event; //键盘码的捕获 var key=e.which||e.keyCode ...
- Selenium+python+shell+crontab+firefox
最近在尝试一个自动打卡的脚本,发现了几个问题,特此记录一下. 环境: Ubuntu 12.04.4 LTS selenium 2.43.0 firefox 32.0.3 1 本来机器上selenium ...
- 二、mysql数据类型
.数值型 ) decimal最大支持65位 ) 最大支持10位的二进制存储模式 bin(column),hex(column) 使用bin(二进制查看)或hex(十六进制查看)查看bit类型数据 .时 ...
- csharp excel interop programming
string fileName = "c:\\a.xlsx"; var application = new Application(); application.Visible = ...
- poj 3463 Sightseeing( 最短路与次短路)
http://poj.org/problem?id=3463 Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissio ...
- 使用Unity拦截一个返回Task的方法
目标 主要是想为服务方法注入公用的异常处理代码,从而使得业务代码简洁.本人使用Unity.Interception主键来达到这个目标.由于希望默认就执行拦截,所以使用了虚方法拦截器.要实现拦截,需要实 ...
- 【概率】COGS 1487:麻球繁衍
Description 万有引力定律: “使物体相互靠近的力的大小与物体的质量成正比——而物体的质量又由同一种力决定.这是一个有趣并且有益的例子,说明了科学是如何用A证明B,再用B证明A的.”——安布 ...
- spoj 379
题是水题 但丫的题目意思太难懂 ....... 英语水平 ...... #include <cstdio> #include <cstring> #include &l ...