POJ 1556 计算几何 判断线段相交

题意:

房间里有n堵墙,每面墙上有两扇门,求从房间最左端中点到最右端中点的最短路径

 

题解:

这题就是考验耐心和仔细的。。。

纯暴力判断,单源最短路都懒得写了,直接floyd搞定。。

和平衡树写得一样长了。。

 

View Code
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <algorithm>
  6 #include <cmath>
  7 
  8 #define N 1000
  9 #define EPS 1e-8
 10 
 11 using namespace std;
 12 
 13 struct LINE
 14 {
 15     double x0,x1,y0,y1;
 16     int bh0,bh1;
 17 }line[N];
 18 
 19 int n,num,cnt,S,T;
 20 double map[N][N],dis[N][N];
 21 
 22 inline void read()
 23 {
 24     cnt=num=0;
 25     double a,b,c,d,e;
 26     for(int i=1;i<=n;i++)
 27     {
 28         scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
 29         ++cnt;
 30         line[cnt].x0=a; line[cnt].y0=0; line[cnt].x1=a; line[cnt].y1=b;
 31         line[cnt].bh0=-1; line[cnt].bh1=++num;
 32         ++cnt;
 33         line[cnt].x0=a; line[cnt].y0=c; line[cnt].x1=a; line[cnt].y1=d;
 34         line[cnt].bh0=++num; line[cnt].bh1=++num;
 35         ++cnt;
 36         line[cnt].x0=a; line[cnt].y0=e; line[cnt].x1=a; line[cnt].y1=10;
 37         line[cnt].bh0=++num; line[cnt].bh1=-1;
 38     }
 39 }
 40 
 41 inline void floyd()
 42 {
 43     for(int k=S;k<=T;k++)
 44         for(int i=S;i<=T;i++)
 45             for(int j=S;j<=T;j++)
 46                 map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
 47 }
 48 
 49 inline double cross(double ax,double ay,double bx,double by)
 50 {
 51     return ax*by-ay*bx;
 52 }
 53 
 54 inline bool check(double ax,double ay,double bx,double by)
 55 {
 56     for(int i=1;i<=cnt;i++)
 57     {
 58         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);
 59         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);
 60         if(fg1<-EPS&&fg2<-EPS) return false;
 61     }
 62     return true;
 63 }
 64 
 65 inline double getdis(double ax,double ay,double bx,double by)
 66 {
 67     return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
 68 }
 69 
 70 inline void go()
 71 {
 72     S=0;T=++num;
 73     for(int i=1;i<=cnt;i++)
 74     {
 75         for(int j=i;j<=cnt;j++)
 76         {
 77             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);
 78             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);
 79             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);
 80             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);
 81         }
 82         if(line[i].bh0!=-1)
 83         {
 84             dis[line[i].bh0][S]=dis[S][line[i].bh0]=getdis(0.0,5.0,line[i].x0,line[i].y0);
 85             dis[line[i].bh0][T]=dis[T][line[i].bh0]=getdis(10.0,5.0,line[i].x0,line[i].y0);
 86         }
 87         if(line[i].bh1!=-1)
 88         {
 89             dis[line[i].bh1][S]=dis[S][line[i].bh1]=getdis(0.0,5.0,line[i].x1,line[i].y1);
 90             dis[line[i].bh1][T]=dis[T][line[i].bh1]=getdis(10.0,5.0,line[i].x1,line[i].y1);
 91         }
 92     }
 93     dis[S][T]=dis[T][S]=10.0;
 94     
 95     for(int i=S;i<=T;i++)
 96     {
 97         for(int j=S;j<=T;j++)
 98             map[i][j]=9999999.0;
 99         map[i][i]=0.0;
100     }
101 
102     for(int i=1;i<=cnt;i++)
103         for(int j=i+1;j<=cnt;j++)
104         {
105             if(line[i].bh0!=-1&&line[j].bh0!=-1&&check(line[i].x0,line[i].y0,line[j].x0,line[j].y0))
106                 map[line[i].bh0][line[j].bh0]=map[line[j].bh0][line[i].bh0]=dis[line[j].bh0][line[i].bh0];
107                 
108             if(line[i].bh0!=-1&&line[j].bh1!=-1&&check(line[i].x0,line[i].y0,line[j].x1,line[j].y1))
109                 map[line[i].bh0][line[j].bh1]=map[line[j].bh1][line[i].bh0]=dis[line[j].bh1][line[i].bh0];
110                 
111             if(line[i].bh1!=-1&&line[j].bh0!=-1&&check(line[i].x1,line[i].y1,line[j].x0,line[j].y0))
112                 map[line[i].bh1][line[j].bh0]=map[line[j].bh0][line[i].bh1]=dis[line[j].bh0][line[i].bh1];
113                 
114             if(line[i].bh1!=-1&&line[j].bh1!=-1&&check(line[i].x1,line[i].y1,line[j].x1,line[j].y1))
115                 map[line[i].bh1][line[j].bh1]=map[line[j].bh1][line[i].bh1]=dis[line[j].bh1][line[i].bh1];
116         }
117     for(int i=1;i<=cnt;i++)
118     {
119         if(line[i].bh0!=-1&&check(0.0,5.0,line[i].x0,line[i].y0))
120             map[S][line[i].bh0]=map[line[i].bh0][S]=dis[S][line[i].bh0];
121         if(line[i].bh1!=-1&&check(0.0,5.0,line[i].x1,line[i].y1))
122             map[S][line[i].bh1]=map[line[i].bh1][S]=dis[S][line[i].bh1];
123         if(line[i].bh0!=-1&&check(10.0,5.0,line[i].x0,line[i].y0))
124             map[T][line[i].bh0]=map[line[i].bh0][T]=dis[T][line[i].bh0];
125         if(line[i].bh1!=-1&&check(10.0,5.0,line[i].x1,line[i].y1))
126             map[T][line[i].bh1]=map[line[i].bh1][T]=dis[T][line[i].bh1];
127     }
128     
129     if(check(0.0,5.0,10.0,5.0)) map[S][T]=map[T][S]=dis[S][T];
130     
131     floyd();
132     printf("%.2lf\n",map[S][T]);
133 }
134 
135 int main()
136 {
137     while(scanf("%d",&n))
138     {
139         if(n==-1) break;
140         read(),go();
141     }
142     return 0;
143 } 

 

 

posted @ 2013-01-10 21:09  proverbs  阅读(329)  评论(0编辑  收藏  举报