POJ 1556 计算几何 判断线段相交 最短路
2017-07-20 15:54
531 查看
题意:
在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离。
分析:
既然是求最短距离,很容易想到最短距离的算法。那么接下来就是构造图了,门的两端点为图中的一个结点(不包括边界点),总共有4*n+2个结点。
枚举每一对结点连线,如果经过任意一张门,设距离为INF;否则距离就是它们的直线距离。
数据量不大,直接FLoyd。
在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离。
分析:
既然是求最短距离,很容易想到最短距离的算法。那么接下来就是构造图了,门的两端点为图中的一个结点(不包括边界点),总共有4*n+2个结点。
枚举每一对结点连线,如果经过任意一张门,设距离为INF;否则距离就是它们的直线距离。
数据量不大,直接FLoyd。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define eps 1e-8 #define INF 1e9 using namespace std; const int maxn=1000+5; double g[maxn][maxn]; int n; typedef struct Point { double x,y; Point() {}; Point(double xx,double yy) { x=xx; y=yy; } } Vector; Point pot[maxn]; double crs_prdct(Vector a,Vector b) { return a.x*b.y-b.x*a.y; } double get_distance(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } Vector operator - (Point a,Point b) { return Vector(a.x-b.x,a.y-b.y); } bool intersect(Point p1,Point p2,Point q1,Point q2) { double crsp1=crs_prdct(q1-p1,q2-p1); double crsp2=crs_prdct(q1-p2,q2-p2); if(fabs(crsp1)<eps || fabs(crsp2)<eps) return true; return crsp1*crsp2<0? true:false; } int main() { // freopen("in.txt","r",stdin); pot[0]=Point(0,5); while(scanf("%d",&n) && n!=-1) { double x,y1,y2,y3,y4; for(int i=0; i<n; i++) { scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4); pot[4*i+1]=Point(x,y1); pot[4*i+2]=Point(x,y2); pot[4*i+3]=Point(x,y3); pot[4*i+4]=Point(x,y4); } pot[4*n+1]=Point(10,5); memset(g,0,sizeof(g)); for(int i=0; i<4*n+2; i++) { for(int j=i+1; j<4*n+2; j++) { int l=(i-1)/4,r=(j-1)/4; if(i==0) l=-1; bool flag=true; for(int k=l+1; k<r; k++) { if(intersect(Point(pot[4*k+1].x,0),pot[4*k+1],pot[i],pot[j])) { flag=false; break; } if(intersect(pot[4*k+2],pot[4*k+3],pot[i],pot[j])) { flag=false; break; } if(intersect(pot[4*k+4],Point(pot[4*k+4].x,10),pot[i],pot[j])) { flag=false; break; } } g[i][j]=g[j][i]=(flag? get_distance(pot[i],pot[j]):INF); } } for(int k=0;k<4*n+2;k++) for(int i=0;i<4*n+2;i++) for(int j=0;j<4*n+2;j++) g[i][j]=min(g[i][j],g[i][k]+g[k][j]); printf("%.2f\n",g[0][4*n+1]); } return 0; }
相关文章推荐
- POJ 1556 The Doors (计算几何判断线段相交+最短路)
- POJ 1556 计算几何 判断线段相交
- [计算几何]POJ 1556 判断线段相交+Dijkstra
- POJ-1556 线段相交的判断与最短路(几何+图论)
- POJ 1556 The Doors 判断线段相交+最短路
- POJ 1410 Intersection <计算几何(线段相交判断)>
- 【计算几何】 POJ 1127 Jack Straws 判断线段是否相交
- POJ 3304 Segments (计算几何、判断直线与线段是否相交)
- 【计算几何】 POJ 1127 Jack Straws 判断线段是否相交
- poj 1556 The Doors 线段相交判断+最短路
- pku 1556 The Doors 计算几何 之 叉积判断线段是否相交
- POJ 1410(计算几何初步——判断线段与矩形相交,条件恶心的一B啊,又没说清楚)
- poj 1556 The Doors(最短路+判断线段相交)
- POJ 1556 线段相交于最短路——几何问题转换为图问题
- POJ 2653 Pick-up sticks(计算几何,判断线段相交)
- POJ 1127 基础计算几何(判断两线段相交)+并查集
- POJ 1556 The Doors(判断线段相交 && 最短路)
- POJ 3304(计算几何初步——判断线段和直线相交,加上枚举)
- POJ 1556 The Doors(判断线段相交 && 最短路)
- POJ 1039——计算几何初步(判断线段与直线相交)