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 ...
随机推荐
- iOS分辨率的那些事儿(转)
1 iOS设备的分辨率 iOS设备,目前最主要的有3种(Apple TV等不在此讨论),按分辨率分为两类 iPhone/iPod Touch 普屏分辨率 320像素 x 480像素 Retina ...
- RHEL5 yum更新源
1.检查yum是否安装 rpm -qa |grep yum 2.利用CentOS的yum更新源来实现RHEL5的YUM功能 vi /etc/yum.repos.d/CentOS-Base.repo [ ...
- 5 -- Hibernate的基本用法 --4 1 创建Configuration对象
org.hibernate.cfg.Configuration实例代表了应用程序到SQL数据库的配置信息,Configuration对象提供了一个buildSessionFactory()方法,该方法 ...
- ios开发之--[_NSInlineData objectForKeyedSubscript:]
reason: '-[_NSInlineData objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7fa2049 ...
- Unity Shader 获取模型空间坐标
CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma ...
- CentOS6.5下安装Oracle11g
一.安装前系统准备 1. 修改主机名 #sed -i "s/HOSTNAME=localhost.localdomain/HOSTNAME=oracledb.01/" /etc/s ...
- java十年技术栈[总结复习用]
以下摘自http://www.tvtv223.com/so/8/default/8.html#36-数据库的分库分表mycat java技术栈 参考了众多资料,这里就不再详细列举了,可以自行去搜索 1 ...
- Visual C++中去除警告
在编程中,编译器警告的意思是提问程序员:如果这样做将会出现意外的错误,你确定要这样做吗? 在很多情况下,我们写程序的时候会出现一些警告,而这些警告我们都知道这样做的确是需要的并且程序中多处出现这种做法 ...
- 【数据处理】SQL Server高效大数据量存储方案SqlBulkCopy
要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储. 一个比较好的解决方案,就是采用SqlBulkCopy来处理存储数据. SqlBulkCopy存储大批量的数 ...
- 【Mybatis】Mybatis基本构成
SqlSessionFactoryBuilder(构造器):它会根据配置信息或者代码来生成SqlSessionFactory(工厂接口) SqlSessionFactory:依靠工厂来生成SqlSes ...