POJ 1556 计算几何 判断线段相交
2013-01-10 21:09
477 查看
题意:
房间里有n堵墙,每面墙上有两扇门,求从房间最左端中点到最右端中点的最短路径
题解:
这题就是考验耐心和仔细的。。。
纯暴力判断,单源最短路都懒得写了,直接floyd搞定。。
和平衡树写得一样长了。。
View Code
房间里有n堵墙,每面墙上有两扇门,求从房间最左端中点到最右端中点的最短路径
题解:
这题就是考验耐心和仔细的。。。
纯暴力判断,单源最短路都懒得写了,直接floyd搞定。。
和平衡树写得一样长了。。
View Code
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #define N 1000 #define EPS 1e-8 using namespace std; struct LINE { double x0,x1,y0,y1; int bh0,bh1; }line ; int n,num,cnt,S,T; double map ,dis ; inline void read() { cnt=num=0; double a,b,c,d,e; for(int i=1;i<=n;i++) { scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e); ++cnt; line[cnt].x0=a; line[cnt].y0=0; line[cnt].x1=a; line[cnt].y1=b; line[cnt].bh0=-1; line[cnt].bh1=++num; ++cnt; line[cnt].x0=a; line[cnt].y0=c; line[cnt].x1=a; line[cnt].y1=d; line[cnt].bh0=++num; line[cnt].bh1=++num; ++cnt; line[cnt].x0=a; line[cnt].y0=e; line[cnt].x1=a; line[cnt].y1=10; line[cnt].bh0=++num; line[cnt].bh1=-1; } } inline void floyd() { for(int k=S;k<=T;k++) for(int i=S;i<=T;i++) for(int j=S;j<=T;j++) map[i][j]=min(map[i][j],map[i][k]+map[k][j]); } inline double cross(double ax,double ay,double bx,double by) { return ax*by-ay*bx; } inline bool check(double ax,double ay,double bx,double by) { for(int i=1;i<=cnt;i++) { int fg1=cross(ax-bx,ay-by,line[i].x0-bx,line[i].y0-by)*cross(ax-bx,ay-by,line[i].x1-bx,line[i].y1-by); int fg2=cross(line[i].x1-line[i].x0,line[i].y1-line[i].y0,ax-line[i].x0,ay-line[i].y0)*cross(line[i].x1-line[i].x0,line[i].y1-line[i].y0,bx-line[i].x0,by-line[i].y0); if(fg1<-EPS&&fg2<-EPS) return false; } return true; } inline double getdis(double ax,double ay,double bx,double by) { return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by)); } inline void go() { S=0;T=++num; for(int i=1;i<=cnt;i++) { for(int j=i;j<=cnt;j++) { if(line[i].bh0!=-1&&line[j].bh0!=-1) dis[line[i].bh0][line[j].bh0]=dis[line[j].bh0][line[i].bh0]=getdis(line[i].x0,line[i].y0,line[j].x0,line[j].y0); if(line[i].bh0!=-1&&line[j].bh1!=-1) dis[line[i].bh0][line[j].bh1]=dis[line[j].bh1][line[i].bh0]=getdis(line[i].x0,line[i].y0,line[j].x1,line[j].y1); if(line[i].bh1!=-1&&line[j].bh0!=-1) dis[line[i].bh1][line[j].bh0]=dis[line[j].bh0][line[i].bh1]=getdis(line[i].x1,line[i].y1,line[j].x0,line[j].y0); if(line[i].bh1!=-1&&line[j].bh1!=-1) dis[line[i].bh1][line[j].bh1]=dis[line[j].bh1][line[i].bh1]=getdis(line[i].x1,line[i].y1,line[j].x1,line[j].y1); } if(line[i].bh0!=-1) { dis[line[i].bh0][S]=dis[S][line[i].bh0]=getdis(0.0,5.0,line[i].x0,line[i].y0); dis[line[i].bh0][T]=dis[T][line[i].bh0]=getdis(10.0,5.0,line[i].x0,line[i].y0); } if(line[i].bh1!=-1) { dis[line[i].bh1][S]=dis[S][line[i].bh1]=getdis(0.0,5.0,line[i].x1,line[i].y1); dis[line[i].bh1][T]=dis[T][line[i].bh1]=getdis(10.0,5.0,line[i].x1,line[i].y1); } } dis[S][T]=dis[T][S]=10.0; for(int i=S;i<=T;i++) { for(int j=S;j<=T;j++) map[i][j]=9999999.0; map[i][i]=0.0; } for(int i=1;i<=cnt;i++) for(int j=i+1;j<=cnt;j++) { if(line[i].bh0!=-1&&line[j].bh0!=-1&&check(line[i].x0,line[i].y0,line[j].x0,line[j].y0)) map[line[i].bh0][line[j].bh0]=map[line[j].bh0][line[i].bh0]=dis[line[j].bh0][line[i].bh0]; if(line[i].bh0!=-1&&line[j].bh1!=-1&&check(line[i].x0,line[i].y0,line[j].x1,line[j].y1)) map[line[i].bh0][line[j].bh1]=map[line[j].bh1][line[i].bh0]=dis[line[j].bh1][line[i].bh0]; if(line[i].bh1!=-1&&line[j].bh0!=-1&&check(line[i].x1,line[i].y1,line[j].x0,line[j].y0)) map[line[i].bh1][line[j].bh0]=map[line[j].bh0][line[i].bh1]=dis[line[j].bh0][line[i].bh1]; if(line[i].bh1!=-1&&line[j].bh1!=-1&&check(line[i].x1,line[i].y1,line[j].x1,line[j].y1)) map[line[i].bh1][line[j].bh1]=map[line[j].bh1][line[i].bh1]=dis[line[j].bh1][line[i].bh1]; } for(int i=1;i<=cnt;i++) { if(line[i].bh0!=-1&&check(0.0,5.0,line[i].x0,line[i].y0)) map[S][line[i].bh0]=map[line[i].bh0][S]=dis[S][line[i].bh0]; if(line[i].bh1!=-1&&check(0.0,5.0,line[i].x1,line[i].y1)) map[S][line[i].bh1]=map[line[i].bh1][S]=dis[S][line[i].bh1]; if(line[i].bh0!=-1&&check(10.0,5.0,line[i].x0,line[i].y0)) map[T][line[i].bh0]=map[line[i].bh0][T]=dis[T][line[i].bh0]; if(line[i].bh1!=-1&&check(10.0,5.0,line[i].x1,line[i].y1)) map[T][line[i].bh1]=map[line[i].bh1][T]=dis[T][line[i].bh1]; } if(check(0.0,5.0,10.0,5.0)) map[S][T]=map[T][S]=dis[S][T]; floyd(); printf("%.2lf\n",map[S][T]); } int main() { while(scanf("%d",&n)) { if(n==-1) break; read(),go(); } return 0; }
相关文章推荐
- POJ 1556 计算几何 判断线段相交 最短路
- [计算几何]POJ 1556 判断线段相交+Dijkstra
- POJ 1556 The Doors (计算几何判断线段相交+最短路)
- POJ-1556 线段相交的判断与最短路(几何+图论)
- POJ 2653 计算几何 判断线段相交
- POJ 3304 Segments [枚举+叉乘判断线段相交]【计算几何】
- POJ 3304(计算几何初步——判断线段和直线相交,加上枚举)
- POJ 3304 Segments (计算几何、判断直线与线段是否相交)
- POJ 2653 Pick-up sticks(计算几何,判断线段相交)
- POJ 3304 Segments(计算几何 判断直线与线段相交)
- 【计算几何】 POJ 1127 Jack Straws 判断线段是否相交
- 【计算几何】 POJ 1127 Jack Straws 判断线段是否相交
- POJ 1410 Intersection <计算几何(线段相交判断)>
- POJ 1039——计算几何初步(判断线段与直线相交)
- POJ 3304 Segments <计算几何(直线与线段相交判断)>
- pku 1556 The Doors 计算几何 之 叉积判断线段是否相交
- POJ 1410(计算几何初步——判断线段与矩形相交,条件恶心的一B啊,又没说清楚)
- POJ 1127 基础计算几何(判断两线段相交)+并查集
- POJ 3347 Kadj Squares (计算几何+线段相交)
- 计算几何----判断线段相交(一)