题目链接:http://poj.org/problem?id=1556

Time Limit: 1000MS Memory Limit: 10000K

Description

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length. 

Input

The input data for the illustrated chamber would appear as follows.


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

The output should contain one line of output for each chamber. The line should contain the minimal path length rounded to two decimal places past the decimal point, and always showing the two decimal places past the decimal point. The line should contain no blanks.

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最短路]的更多相关文章

  1. NOIP2013 华容道 (棋盘建图+spfa最短路)

    #include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...

  2. poj 1556 The Doors(线段相交,最短路)

      The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7430   Accepted: 2915 Descr ...

  3. POJ 1556 The Doors 线段交 dijkstra

    LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...

  4. POJ 1556 - The Doors 线段相交不含端点

    POJ 1556 - The Doors题意:    在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少.    分析:        要么直达,要么 ...

  5. poj 2135 Farm Tour 最小费用最大流建图跑最短路

    题目链接 题意:无向图有N(N <= 1000)个节点,M(M <= 10000)条边:从节点1走到节点N再从N走回来,图中不能走同一条边,且图中可能出现重边,问最短距离之和为多少? 思路 ...

  6. POJ 3687 Labeling Balls 逆向建图,拓扑排序

    题目链接: http://poj.org/problem?id=3687 要逆向建图,输入的时候要判重边,找入度为0的点的时候要从大到小循环,尽量让编号大的先入栈,输出的时候注意按编号的顺序输出重量, ...

  7. Invitation Cards(邻接表+逆向建图+SPFA)

    Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 17538   Accepted: 5721 Description In ...

  8. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

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

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

随机推荐

  1. Redis Cluster 简单安装配置

    1 新建目录 “/app/redis”,输入命令 mkdir -p /app/redis 2 先安装ruby-2.3.1.tar.gz 3 测试ruby是否安装成功,输入命令:gem,如果显示以下信息 ...

  2. Python中的类(下)

    本文将介绍一下类的构造函数和初始化函数,以及如何通过"魔术方法"定制一个类. 类构造和初始化 在前面的文章中,经常使用初始化函数"__init__",下面看看& ...

  3. 【ArcGIS】WebAdaptorIIS 安装前准备及配置Portal For ArcGIS的问题解决

    1.计算机全名配置 2.IIS-服务器证书配置 3.端口绑定 备注:配置Portal For ArcGIS总会提示计算机域名.全名错误.完全限定域名,可能就是没有进行第一步操作 4.Portal目录

  4. iOS开发-UIImageView的contentMode属性

    UIImageView 的contentMode这个属性是用来设置图片的显示方式,如居中.居右,是否缩放等,有以下几个常量可供设定:UIViewContentModeScaleToFillUIView ...

  5. Android开发-- Genymotion模拟器

    模拟器安装 http://blog.csdn.net/beiminglei/article/details/13776013 连接ADB http://android3g.diandian.com/p ...

  6. Unity Shader 自定义纹理坐标变量写法

    Properties { _R(,)) = 1.0 _ColorTex("ColorTex (RGB)", 2D) = "red" {} struct Inpu ...

  7. mosquitto 参数配置

    mosquitto 参数配置 1.retry_interval  当QoS为1或2的消息已经被发送后,mosquitto在一段时间内仍未接收到客户端的反馈消息,将重新发送消息. 默认为20秒 2.sy ...

  8. call()、apply()、bind()

    1.均可以改变函数的执行上下文,也就是this值: 2.call()  apply() function apply(num1, num2){ return sum.apply(this, [num1 ...

  9. linux个性化定制登录信息

    1./etc/motd /etc/motd即messageoftoday(布告栏信息),每次用户登录时,/etc/motd文件的内容会显示在用户的终端.系统管理员可以在文件中编辑系统活动消息,例如:管 ...

  10. PON系统基础知识简介

    一  PON基础知识 1.1 PON技术概念 PON(Passive Optical Network)即无源光网络,一种基于点到多点(P2MP)拓朴的技术.“无源”指ODN(光分配网络)不含有任何电子 ...