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. android银行卡匹配、详情展开动画、仿爱奇艺视频拖拽、扫码识别手机号等源码

    Android精选源码 android实现银行卡匹配信息源码 android实现可以展开查看详情的卡片 下拉刷新,上拉加载,侧滑显示菜单等效果RefreshSwipeRecyclerview andr ...

  2. the quick brown fox jumps over the lazy dog

    THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

  3. 动态链接库(DLL)编写经验

    我首先说明DLL的生成方法,之后再补充一些特殊之处. 生成方法: 1.对需要导出的类,在头文件中添加 #ifdef CLASS _API #define CLASS_API _declspec(dll ...

  4. Actor-ES框架:Ray

    并发 1. 并发和并行 并发:两个或多个任务在同一时间段内运行.关注点在任务分割. 并行:两个或多个任务在同一时刻同时运行.关注点在同时执行. 本文大多数情况下不会严格区分这两个概念,默认并发就是指并 ...

  5. 如何动态修改网页的标题(title)?

    有时候我们需要复用一个页面,但是又希望他们拥有各自的标题,这时候就需要动态的去更改页面的title了,不然所有页面都是一个标题. 这时候就会想到使用js或jQuery去实现了. 1.js方式. 首先, ...

  6. for语句,你真正搞懂了吗?

    今天看书时,无意间看到了这个知识点,啥知识点?也许在各位大神看来,那是再简单不过的东西了. 说来惭愧.原来直到今天我才真正搞懂for语句. for语句的结构如下所示: for(语句A;语句B;语句C) ...

  7. HDU 1213 How Many Tables(模板——并查集)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1213 Problem Description Today is Ignatius' birthday ...

  8. .31-浅析webpack源码之doResolve事件流(2)

    放个流程图: 这里也放一下request对象内容,这节完事后如下(把vue-cli的package.json也复制过来了): /* { context: { issuer: '', compiler: ...

  9. union 时只能查出一个表中的信息,另一个表只能查出字段

    原因:news表中title字段的编码,与brand表中的编码不一致导致 y

  10. 把VueThink整合到已有ThinkPHP 5.0项目中

     享 关键字: VueThink ThinkPHP5.0 Vue2.x TP5 管理后台扩展 VueThink初认识 VueThink,是一个很不错的技术框架,由广州洪睿科技的技术团队2016年研发( ...