POJ 1556 - The Doors - [平面几何+建图spfa最短路]
题目链接:http://poj.org/problem?id=1556
Time Limit: 1000MS Memory Limit: 10000K
Description

Input
2
4 2 7 8 9
7 3 4.5 6 7
The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1.
Output
Sample Input
1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1
Sample Output
10.00
10.06
题意:
给出一个(0,0)(0,10)(10,0)(10,10)的正方形房子,里面有一些墙,每堵墙上有两扇门;
求从(0,5)到(10,5)的最短距离;
题解:
是一道不错的题目,一定程度上结合了计算几何和最短路;
建一个有向图,把(0,5)作为起始点,(10,5)作为目标点,其他所有墙上的门的两个端点也加入到这个有向图中;
尝试枚举连接任意两个点,只有当这两个点之间没有墙阻隔,这连个点才可能连接起来;
所有能连接起来的两个点都作为一条有向边加入到有向图中,并且靠左的作为u,靠右的作为v,而两点之间的距离作为w;
最后,我们只要求出起始点和目标点之间的最短路即可。
AC代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>
#define MAXN 4*20
#define INF 0x3f3f3f3f
using namespace std; //--------------------------------------计算几何模板 - st-------------------------------------- const double eps = 1e-; struct Point{
double x,y;
Point(double tx=,double ty=):x(tx),y(ty){}
};
typedef Point Vctor; //向量的加减乘除
Vctor operator + (Vctor A,Vctor B){return Vctor(A.x+B.x,A.y+B.y);}
Vctor operator - (Point A,Point B){return Vctor(A.x-B.x,A.y-B.y);}
Vctor operator * (Vctor A,double p){return Vctor(A.x*p,A.y*p);}
Vctor operator / (Vctor A,double p){return Vctor(A.x/p,A.y/p);} int dcmp(double x)
{
if(fabs(x)<eps) return ;
else return (x<)?(-):();
}
bool operator == (Point A,Point B){return dcmp(A.x-B.x)== && dcmp(A.y-B.y)==;} //向量的点积,长度,夹角
double Dot(Vctor A,Vctor B){return A.x*B.x+A.y*B.y;}
double Length(Vctor A){return sqrt(Dot(A,A));}
double Angle(Vctor A,Vctor B){return acos(Dot(A,B)/Length(A)/Length(B));} //叉积,三角形面积
double Cross(Vctor A,Vctor B){return A.x*B.y-A.y*B.x;}
double TriangleArea(Point A,Point B,Point C){return Cross(B-A,C-A);} //判断线段是否规范相交
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
double c1 = Cross(a2 - a1,b1 - a1), c2 = Cross(a2 - a1,b2 - a1),
c3 = Cross(b2 - b1,a1 - b1), c4 = Cross(b2 - b1,a2 - b1);
return dcmp(c1)*dcmp(c2)< && dcmp(c3)*dcmp(c4)<;
} //--------------------------------------计算几何模板 - ed-------------------------------------- //--------------------------------------spfa算法 - st--------------------------------------
double d[MAXN];
double mp[MAXN][MAXN];
bool vis[MAXN];
void init(int n){for(int i=;i<n;i++) for(int j=;j<n;j++) mp[i][j]=;}
void addedge(int u,int v,double w){mp[u][v]=w;}
void spfa(int st,int n)
{
for(int i=;i<n;i++)
{
i==st ? d[i]= : d[i]=INF;
vis[i]=;
}
queue<int> q;
q.push(st);
vis[st]=;
while(!q.empty())
{
int u=q.front();q.pop();vis[u]=;
for(int v=;v<n;v++)
{
if(u==v || mp[u][v]==) continue;
double tmp=d[v];
if(d[v]>d[u]+mp[u][v]) d[v]=d[u]+mp[u][v];
if(d[v]<tmp && !vis[v])
{
q.push(v);
vis[v]=;
}
}
}
}
//--------------------------------------spfa算法 - ed-------------------------------------- int n;
vector<Point> p;
int main()
{
while(scanf("%d",&n) && n!=-)
{
p.clear();
p.push_back(Point(,));
for(int i=;i<=n;i++)
{
double x,y1,y2,y3,y4;
scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
p.push_back(Point(x,y1));
p.push_back(Point(x,y2));
p.push_back(Point(x,y3));
p.push_back(Point(x,y4));
}
p.push_back(Point(,)); int _size=p.size();
init(_size);
for(int i=;i<_size;i++)
{
for(int j=i+;j<_size;j++)
{
if(p[i].x==p[j].x) continue; bool ok=;
for(int k=i+;k<j;k++)
{
if(k%==)
{
if(SegmentProperIntersection(p[i],p[j],p[k],Point(p[k].x,)))
{
ok=;
break;
}
}
else if(k%==)
{
if(SegmentProperIntersection(p[i],p[j],p[k],p[k+]))
{
ok=;
break;
}
}
else if(k%==)
{
if(SegmentProperIntersection(p[i],p[j],p[k],p[k-]))
{
ok=;
break;
}
}
else if(k%==)
{
if(SegmentProperIntersection(p[i],p[j],p[k],Point(p[k].x,)))
{
ok=;
break;
}
}
}
if(ok) addedge(i,j,Length(p[i]-p[j]));
}
} spfa(,_size);
printf("%.2f\n",d[_size-]);
}
}
POJ 1556 - The Doors - [平面几何+建图spfa最短路]的更多相关文章
- NOIP2013 华容道 (棋盘建图+spfa最短路)
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...
- poj 1556 The Doors(线段相交,最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7430 Accepted: 2915 Descr ...
- POJ 1556 The Doors 线段交 dijkstra
LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...
- POJ 1556 - The Doors 线段相交不含端点
POJ 1556 - The Doors题意: 在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少. 分析: 要么直达,要么 ...
- poj 2135 Farm Tour 最小费用最大流建图跑最短路
题目链接 题意:无向图有N(N <= 1000)个节点,M(M <= 10000)条边:从节点1走到节点N再从N走回来,图中不能走同一条边,且图中可能出现重边,问最短距离之和为多少? 思路 ...
- POJ 3687 Labeling Balls 逆向建图,拓扑排序
题目链接: http://poj.org/problem?id=3687 要逆向建图,输入的时候要判重边,找入度为0的点的时候要从大到小循环,尽量让编号大的先入栈,输出的时候注意按编号的顺序输出重量, ...
- Invitation Cards(邻接表+逆向建图+SPFA)
Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 17538 Accepted: 5721 Description In ...
- CF786B Legacy 线段树优化建图 + spfa
CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
随机推荐
- jquery获取元素颜色css('color')的值返回RGB
css代码如下: a, a:link, a:visited { color:#4188FB; } a:active, a:focus, a:hover { color:#FFCC00; } js代码如 ...
- Apache性能优化总结
1.介绍 首先要了解Apache采用的MPM(Multi -Processing Modules,多道处理模块),MPM是Apache的核心,它的作用是管理网络连接.调度请求.Apache2.0中MP ...
- Java -- 异常的捕获及处理 -- throws与throw关键字
7.2 throws 与 throw关键字 7.2.1 throws 关键字 在定义一个方法时可以使用throws关键字声明,使用throws声明的方法标识此方法不处理异常,而交给方法的调用处进行处理 ...
- Android实现图片缩放示例
package com.example.demo; import android.os.Bundle; import android.app.Activity; import android.grap ...
- python --help查询python相关命令
C:\Users\lenovo>python --help usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ... O ...
- IIS中采用ISAPI-Rewrite防盗链
本规则支持白名单排除式防盗链,搜索引擎友好(不屏蔽),被盗链后的错误提示转向,支持各种文件类型,经作者亲验真的能用,第一时间在itmop.com原创发表,请继续往下阅读. 近来小站遇到了盗链问题,至使 ...
- centos6.4搭建ftp服务器
在centos环境下搭建ftp服务器,选择用vsftpd. 1.检测是否已经安装vsftpd # rpm -qa | grep vsftpd 如果已经安装vsftpd,会显示相应版本号.没有任何提示, ...
- js 中的break continue return
break:跳出整个循环 1.当i=6时,就跳出了整个循环,此for循环就不继续了: continue:跳出当前循环,继续下一次循环: return :指定函数返回值 1.在js当中,常使用retur ...
- codeforces水题100道 第一题 Codeforces Beta Round #1 A. Theatre Square (math)
题目链接:http://www.codeforces.com/problemset/problem/1/A题意:至少用多少块边长为a的方块铺满NxM的矩形区域.C++代码: #include < ...
- Android学习之蓝牙操作
BluetoothAdapter 用法 蓝牙运行原理:通过BluetoothAdapter 蓝牙适配器处理任务,如果蓝牙被启动之后,系统会自动去搜索其它设备,如果匹配到附近的设备就发送一个广播,Bro ...