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 } 

 

 

你可能感兴趣的:(poj)