最短路+线段交 POJ 1556 好题

Posted blues

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最短路+线段交 POJ 1556 好题相关的知识,希望对你有一定的参考价值。

  1 // 最短路+线段交 POJ 1556 好题
  2 // 题意:从(0,5)到(10,5)的最短距离,中间有n堵墙,每堵上有两扇门可以通过
  3 // 思路:先存图。直接n^2来暴力,不好写。分成三部分,起点 终点和之间的点:中间点之间:起点和终点的距离
  4 // n最大为18所以直接n^3最短路
  5 
  6 
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <map>
 12 #include <set>
 13 #include <queue>
 14 #include <stdlib.h>
 15 #include <cmath>
 16 using namespace std;
 17 typedef long long LL;
 18 const double inf = 1e9;
 19 const int N = 5000;
 20 const double eps = 1e-8;
 21 void fre() {freopen("in.txt","r",stdin);}
 22 
 23 int sgn(double x){
 24     if(fabs(x)<eps) return  0;
 25     if(x<0) return -1;
 26     return 1;
 27 }
 28 
 29 struct Point{
 30     double x,y;
 31     Point(){}
 32     Point(double _x,double _y){
 33         x=_x;y=_y;
 34     }
 35     Point operator -(const Point &b)const{
 36         return Point(x-b.x,y-b.y);
 37     }
 38     double operator *(const Point &b)const{
 39         return x*b.x+y*b.y;
 40     }
 41     double operator ^(const Point &b)const{
 42         return x*b.y-y*b.x;
 43     } 
 44 };
 45 
 46 struct Line{
 47     Point s,e;
 48     Line(){}
 49     Line(Point _s,Point _e){
 50         s=_s,e=_e;
 51     }
 52 };
 53 Line line[N];
 54 double xmult(Point p0,Point p1,Point p2){
 55     return (p1-p0)^(p2-p0);
 56 }
 57 
 58 double dist(Point a,Point b){
 59     return sqrt((a-b)*(a-b));
 60 }
 61 
 62 bool inter(Line l1,Line l2){
 63     return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
 64 }
 65 
 66 double d[100][100];
 67 int main(){
 68     // fre();
 69     int n;
 70     while(~scanf("%d",&n)){
 71         if(n==-1) break;
 72         // clc(d,
 73         for(int i=0;i<=4*n+1;i++){
 74             for(int j=0;j<=4*n+1;j++){
 75                 if(i==j) d[i][j]=0;
 76                 else d[i][j]=inf;
 77             }
 78         }
 79         for(int i=1;i<=n;i++){
 80             double x,y3,y1,y4,y2;
 81             scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
 82             line[i*2-1]=Line(Point(x,y1),Point(x,y2));
 83             line[i*2]=Line(Point(x,y3),Point(x,y4));
 84         }
 85         bool flag;
 86         for(int i=1;i<=4*n;i++){
 87             flag=true;
 88             int cn=(i+3)/4;
 89             Point tem;
 90             if(i&1) tem=line[(i+1)/2].s;
 91             else tem=line[(i+1)/2].e;
 92             for(int j=1;j<cn;j++){
 93                 if(inter(line[j*2-1],Line(Point(0,5),tem))==false&&inter(line[j*2],Line(Point(0,5),tem))==false){
 94                     flag=false;
 95                     break;
 96                 }
 97             }
 98             if(flag) d[0][i]=d[i][0]=dist(Point(0,5),tem);
 99             flag=true;
100             for(int j=cn+1;j<=n;j++){
101                 if(inter(line[j*2-1],Line(Point(10,5),tem))==false&&inter(line[j*2],Line(Point(10,5),tem))==false){
102                     flag=false;
103                     break;
104                 }
105             }
106             if(flag) d[4*n+1][i]=d[i][4*n+1]=dist(Point(10,5),tem);
107         }
108         flag=true;
109         for(int i=1;i<=4*n;i++){
110             for(int j=i+1;j<=4*n;j++){
111                flag=true;
112                Point p1,p2;
113                int cn1,cn2;
114                cn1=(i+3)/4;
115                cn2=(j+3)/4;
116                if(i&1) p1=line[(i+1)/2].s;
117                else p1=line[(i+1)/2].e;
118                if(j&1) p2=line[(j+1)/2].s;
119                else p2=line[(j+1)/2].e;
120                for(int cn=cn1+1;cn<cn2;cn++){
121                     if(inter(line[cn*2-1],Line(p1,p2))==false&&inter(line[cn*2],Line(p1,p2))==false){
122                       flag=false;
123                       break;
124                     }
125                }
126                if(flag) d[i][j]=d[j][i]=dist(p1,p2);
127             }
128         }
129         flag=true;
130         for(int i=1;i<=n;i++){
131             if(inter(line[i*2-1],Line(Point(0,5),Point(10,5)))==false&&inter(line[i*2],Line(Point(0,5),Point(10,5)))==false){
132                 flag=false;
133                 break;
134             }
135         }
136         if(flag) d[0][4*n+1]=d[4*n+1][0]=dist(Point(0,5),Point(10,5));
137         for(int i=0;i<=4*n+1;i++){
138             for(int j=0;j<=4*n+1;j++){
139                 for(int k=0;k<=4*n+1;k++){
140                     if(d[i][k]+d[k][j]<d[i][j]) d[i][j]=d[i][k]+d[k][j];
141                 }
142             }
143         }
144         printf("%.2f\n",d[0][4*n+1]);
145     }
146     return 0;
147 }

 

以上是关于最短路+线段交 POJ 1556 好题的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1556 The Doors 线段交 dijkstra

poj 1556 题解

POJ_1556_The Doors_判断线段相交+最短路

POJ-1556 The Doors---线段相交+最短路

POJ1556计算几何最短路

POJ1556 The Doors 叉积+最短路