The Doors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 8334   Accepted: 3218

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

Source


题意:从(0,5)走到(10,5)最短路

我太傻逼了,查了好长时间计算几何的错,结果是求DAG的DP忘清空vis了
 
线段相交做两个直线与线段相交就行了
注意本题一个端点在另一条线上不能算相交哦
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=,M=1e4+;
const double INF=1e9;
const double eps=1e-;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
inline int sgn(double x){
if(abs(x)<eps) return ;
else return x<?-:;
}
struct Vector{
double x,y;
Vector(double a=,double b=):x(a),y(b){}
bool operator <(const Vector &a)const{
return x<a.x||(x==a.x&&y<a.y);
}
void print(){
printf("%lf %lf\n",x,y);
}
};
typedef Vector Point;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);}
bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==&&sgn(a.y-b.y)==;} double Cross(Vector a,Vector b){
return a.x*b.y-a.y*b.x;
}
double DisPP(Point a,Point b){
Point t=a-b;
return sqrt(t.x*t.x+t.y*t.y);
}
struct Line{
Point s,t;
Line(){}
Line(Point p,Point v):s(p),t(v){}
}l[N];
int cl;
bool isLSI(Line l1,Line l2){
Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s;
return sgn(Cross(v,u))!=sgn(Cross(v,w))&&sgn(Cross(v,u))!=&&sgn(Cross(v,w))!=;
}
bool isSSI(Line l1,Line l2){
return isLSI(l1,l2)&&isLSI(l2,l1);
}
bool can(Point a,Point b){
Line line(a,b);
for(int i=;i<=cl;i++)
if(isSSI(l[i],line)) return false;
return true;
} int n,s,t;
struct edge{
int v,ne;
double w;
}e[M<<];
int h[N],cnt=;
inline void ins(int u,int v,double w){//printf("ins %d %d %lf\n",u,v,w);
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
}
double d[N];
int vis[N]; double dp(int u){
if(vis[u]) return d[u];
vis[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
d[u]=min(d[u],dp(v)+e[i].w);
}
return d[u];
}
void DAG(){
for(int i=s;i<=t;i++) d[i]=INF;
memset(vis,,sizeof(vis));
d[t]=;vis[t]=;
dp(s);
} Point p[N][];
Point S(,),T(,);
inline int idx(int u){return u%==?u/:u/+;}
inline int idy(int u){return u%==?:u%;}
double x;
int main(int argc, const char * argv[]) {
while(true){
n=read();s=;t=*n+;
if(n==-) break;
cnt=;memset(h,,sizeof(h));
cl=; for(int i=;i<=n;i++){
scanf("%lf%lf%lf%lf%lf",&x,&p[i][].y,&p[i][].y,&p[i][].y,&p[i][].y);
p[i][].x=p[i][].x=p[i][].x=p[i][].x=x;
int num=(i-)*;
//for(int j=1;j<=4;j++) p[i][j].print();
if(i==){
for(int j=;j<=;j++)
ins(s,num+j,DisPP(S,p[i][j]));
}else{
for(int j=;j<=;j++){
for(int u=;u<=num;u++){
if(can(p[idx(u)][idy(u)],p[i][j]))
ins(u,num+j,DisPP(p[idx(u)][idy(u)],p[i][j]));
}
if(can(S,p[i][j])) ins(s,num+j,DisPP(S,p[i][j]));
}
}
l[++cl]=Line(Point(x,),p[i][]);
l[++cl]=Line(p[i][],p[i][]);
l[++cl]=Line(p[i][],Point(x,));
}
int num=n*;
for(int u=;u<=num;u++)
if(can(p[idx(u)][idy(u)],T))
ins(u,t,DisPP(p[idx(u)][idy(u)],T));
if(can(S,T)) {puts("10.00");continue;}
DAG();
printf("%.2f\n",d[s]);
} return ;
}
 

POJ1556 The Doors [线段相交 DP]的更多相关文章

  1. POJ1556 最短路 + 线段相交问题

    POJ1556 题目大意:比较明显的题目,在一个房间中有几堵墙,直着走,问你从(0,5)到(10,5)的最短路是多少 求最短路问题,唯一变化的就是边的获取,需要我们获取边,这就需要判断我们想要走的这条 ...

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

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

  3. POJ 1556 The Doors【最短路+线段相交】

    思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...

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

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

  5. POJ 1066 Treasure Hunt (线段相交)

    题意:给你一个100*100的正方形,再给你n条线(墙),保证线段一定在正方形内且端点在正方形边界(外墙),最后给你一个正方形内的点(保证不再墙上) 告诉你墙之间(包括外墙)围成了一些小房间,在小房间 ...

  6. 简单几何(线段相交) POJ 1066 Treasure Hunt

    题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...

  7. poj 1066 线段相交

    链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Subm ...

  8. POJ 1066 Treasure Hunt(线段相交判断)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4797   Accepted: 1998 Des ...

  9. 线段相交 poj 1066

    // 线段相交 poj 1066 // 思路:直接枚举每个端点和终点连成线段,判断和剩下的线段相交个数 // #include <bits/stdc++.h> #include <i ...

随机推荐

  1. 修改mysql密码的四种方法

    方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...

  2. Windows 部署 Redis 群集(转)

    1,下载Redis for windows 的最新版本,解压到 c:\Redis 目录下备用https://github.com/MSOpenTech/redis/releases当前我使用的是 3. ...

  3. Spark高可用集群搭建

    Spark高可用集群搭建 node1    node2    node3   1.node1修改spark-env.sh,注释掉hadoop(就不用开启Hadoop集群了),添加如下语句 export ...

  4. iptables命令 高级网络

    http://man.linuxde.net/iptables iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分.可以直接配置,也可以通过许多前端和图形界面配置. ...

  5. Python3 的函数(2)

    1.形参和实参 def MyFun(x): return x ** 3 y = 3 print(MyFun(y)) x为形参,y为实参. 2.函数文档 在函数内用单引号引起来的一段文字,在调用函数时不 ...

  6. Java Servlet API中文说明文档

    Java Servlet API中文说明文档 目 录 1.... Servet资料 1.1      绪言 1.2      谁需要读这份文档 1.3      Java Servlet API的组成 ...

  7. start tomcat with debugging mode

    For this, you must run your application in debug mode, which requires below parameters. -Xdebug -Xru ...

  8. 从arduino到32单片机的转型

    #include "stm32f10x.h" #include "led.h" #include "delay.h" int main(vo ...

  9. linkin大话数据结构--Collection和Iterator

    linkin大话数据结构--Collection和Iterator Java 集合就像一种容器,可以把多个对象的引用放入容器中.Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系 ...

  10. 使用jQuery的ajax调用action的例子

    直接使用ajax请求会比较繁琐,但是jQuery为我们提供了简单使用ajax的方法. 下面是一个在jQuery easyUI中,利用ajax请求,使下拉菜单关联文本框的例子.其中ajax请求就是8-1 ...