POJ1556 The Doors [线段相交 DP]
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 8334 | Accepted: 3218 |
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
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]的更多相关文章
- POJ1556 最短路 + 线段相交问题
POJ1556 题目大意:比较明显的题目,在一个房间中有几堵墙,直着走,问你从(0,5)到(10,5)的最短路是多少 求最短路问题,唯一变化的就是边的获取,需要我们获取边,这就需要判断我们想要走的这条 ...
- POJ 1556 - The Doors 线段相交不含端点
POJ 1556 - The Doors题意: 在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少. 分析: 要么直达,要么 ...
- POJ 1556 The Doors【最短路+线段相交】
思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
- POJ 1066 Treasure Hunt (线段相交)
题意:给你一个100*100的正方形,再给你n条线(墙),保证线段一定在正方形内且端点在正方形边界(外墙),最后给你一个正方形内的点(保证不再墙上) 告诉你墙之间(包括外墙)围成了一些小房间,在小房间 ...
- 简单几何(线段相交) POJ 1066 Treasure Hunt
题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...
- poj 1066 线段相交
链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS Memory Limit: 10000K Total Subm ...
- POJ 1066 Treasure Hunt(线段相交判断)
Treasure Hunt Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4797 Accepted: 1998 Des ...
- 线段相交 poj 1066
// 线段相交 poj 1066 // 思路:直接枚举每个端点和终点连成线段,判断和剩下的线段相交个数 // #include <bits/stdc++.h> #include <i ...
随机推荐
- [国嵌攻略][091][TCP网络程序设计]
server.c #include <sys/socket.h> #include <netinet/in.h> #include <strings.h> #inc ...
- POJ 3829 Seat taking up is tough(——只是题目很长的模拟)
题目链接: http://poj.org/problem?id=3829 题意描述: 输入矩阵的大小n和m,以及来占位置的人数k 输入n*m的教室座位矩阵,每个值表示该座位的满意度 输入每个人来占位置 ...
- 【深度学习系列】PaddlePaddle可视化之VisualDL
上篇文章我们讲了如何对模型进行可视化,用的keras手动绘图输出CNN训练的中途结果,本篇文章将讲述如何用PaddlePaddle新开源的VisualDL来进行可视化.在讲VisualDL之前,我们先 ...
- Hadoop问题:The auxService:mapreduce_shuffle does not exist
问题描述:The auxService:mapreduce_shuffle does not exist INFO mapreduce.Job: Task Id : attempt_146180833 ...
- JS中获取session中传过来的值对象
摘录自:http://www.360doc.com/content/11/0316/13/5790498_101627263.shtml 把某一对象置于session范围内,并在JSP页面中提取ses ...
- This is probably because there is no OLE editor registered against the type of file you were trying to open.
Reason: This is probably because there is no OLE editor registered against the type of file you were ...
- React版本更新及升级须知(持续更新)
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 18.0px "PingFang SC Semibold& ...
- 基础 - 32位操作系统最多只支持4G内存。
32位操作系统最多只支持4G内存. CPU能不能直接访问硬盘的数据呢, 不能. 只能通过把硬盘的数据先放到内存里, 然后再从内存里访问硬盘的数据.我们平时玩游戏碰上读图loading 进度条的这个过程 ...
- Linuxc - C语言下return 0的意义
两条指令同时执行,前提是第一条指令返回0.否则不执行第二条指令. root@jiqing-virtual-machine:~/cspace/les3# gcc main.c -o main.out & ...
- css FlexBox 弹性盒子常用方法总结
总结一下弹性盒子常用的方法,弹性盒子的功能强大,这次我做了兼容性的felxbox,虽然代码多了一点,但在项目时候可以直接复制过来用,同时在项目上线的时候,如果这时候弹性盒子出了兼容问题,那就可急了~ ...