POJ1556+几何+dij+线段相交

注意:

注意判断两点是否能相连,需要判断这两点之间是否含有其他的线段。。。

同一列的墙 我用的是flag来标记。。

View Code
  1 /*

  2 dij+两点间距离

  3 */

  4 #include<stdio.h>

  5 #include<string.h>

  6 #include<stdlib.h>

  7 #include<algorithm>

  8 #include<iostream>

  9 #include<math.h>

 10 using namespace std;

 11 

 12 const int maxn = 205;//point number

 13 const int maxm = 105;//line number

 14 const double inf = 99999999;

 15 const double eps = 1e-8;

 16 

 17 struct POINT{

 18     double x,y;

 19     int f;

 20 }S,T;

 21 

 22 struct LINE{

 23     double x1,y1,x2,y2;

 24     int f;

 25 };

 26 

 27 int cnt_line,cnt_point;

 28 POINT point[ maxn ];

 29 LINE line[ maxm ];

 30 double mat[ maxn ][ maxn ];

 31 

 32 double dist( POINT a,POINT b ){

 33     double sum = (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);

 34     return sqrt( sum );

 35 }

 36 

 37  double xmult( POINT a,POINT b,POINT c ){

 38      return ( a.x-c.x )*( b.y-c.y )-( a.y-c.y )*( b.x-c.x );

 39  }

 40  

 41  bool inLine( LINE now,POINT p ){

 42      double minx,maxx,miny,maxy;

 43      minx=min( now.x1,now.x2 );

 44      maxx=max( now.x1,now.x2 );

 45      miny=min( now.y1,now.y2 );

 46      maxy=max( now.y1,now.y2 );

 47      if( p.x>=minx&&p.x<=maxx&&p.y>=miny&&p.y<=maxy )

 48          return true;

 49      else

 50          return false;

 51  }

 52  

 53 int Intersection( LINE one,LINE two ){

 54      double d1,d2,d3,d4;

 55      POINT t1,t2,t3,t4;

 56      t1.x = one.x1,t1.y = one.y1,t2.x = one.x2,t2.y = one.y2;

 57      t3.x = two.x1,t3.y = two.y1,t4.x = two.x2,t4.y = two.y2;

 58      d1=xmult( t3,t2,t1 );

 59      d2=xmult( t4,t2,t1 );

 60      d3=xmult( t1,t3,t4 );

 61      d4=xmult( t2,t3,t4 );

 62      if( d1*d2<0&&d3*d4<0 )

 63          return 1;//相互跨过

 64      if( d1==0&&inLine( one,t3 )==true )

 65          return true;

 66      if( d2==0&&inLine( one,t4 )==true )

 67          return true;

 68      if( d3==0&&inLine( two,t1 )==true )

 69          return true;

 70      if( d4==0&&inLine( two,t2 )==true )

 71          return 2;//分别表示某个点在一条直线上的情况

 72      return 0;

 73  }

 74 

 75 void init(){

 76     cnt_line = cnt_point = 0;

 77     for( int i=0;i<maxn;i++ ){

 78         for( int j=0;j<maxn;j++ ){

 79             mat[ i ][ j ] = inf;

 80         }

 81     }

 82 }//init

 83 

 84 void addline( double x1,double y1,double x2,double y2 ){

 85     line[ cnt_line ].x1=x1,line[ cnt_line ].y1=y1;

 86     line[ cnt_line ].x2=x2,line[ cnt_line ].y2=y2;

 87     cnt_line++;

 88 }

 89 

 90 void addpoint( double x,double y ){

 91     point[ cnt_point ].x = x;

 92     point[ cnt_point ].y = y;

 93     cnt_point++;

 94 }

 95 

 96 bool test( POINT a,POINT b ){

 97     LINE tt;

 98     tt.x1 = a.x,tt.y1 = a.y;

 99     tt.x2 = b.x,tt.y2 = b.y;

100     //printf("a.flag:%d b.flag:%d\n",a.f,b.f);

101     for( int i=0;i<cnt_line;i++ ){

102         if( a.f!=line[ i ].f && b.f!=line[ i ].f && Intersection( tt,line[ i ] )==1 )

103             return false;

104     }

105     return true;

106 }

107 

108 double dij( int s,int t ){

109     int vis[ maxn ];

110     double dis[ maxn ];

111     for( int i=0;i<cnt_point;i++ ){

112         dis[ i ] = mat[ s ][ i ];

113         vis[ i ] = 0;

114     }

115     dis[ s ] = 0;

116     vis[ s ] = 1;

117     //double sum = 0;

118     for( int i=0;i<cnt_point;i++ ){

119         int k;

120         double tmax;

121         k =-1,tmax = inf;

122         for( int j=0;j<cnt_point;j++ ){

123             if( vis[ j ]==0&&tmax>dis[ j ] ){

124                 tmax = dis[ j ];

125                 k=j;

126             }

127         }

128         if( k==-1 ) break;

129         vis[ k ] = 1;

130         //sum += tmax;

131         for( int j=0;j<cnt_point;j++ ){

132             if( vis[ j ]==0&&dis[ j ]>dis[ k ]+mat[ k ][ j ] ){

133                 dis[ j ] = dis[ k ]+mat[ k ][ j ];

134             }

135         }

136     }

137     return dis[ t ];

138 }

139 

140 int main(){

141     int m;

142     while( scanf("%d",&m),m!=-1 ){

143         init();

144         S.x = 0.0,S.y = 5.0;

145         T.x = 10.0,T.y = 5.0;

146         if( m==0 ){

147             printf("%.2lf\n",dist( S,T ));

148             continue;

149         }

150         int flag = 0;

151         point[ cnt_point ].f = flag++;

152         addpoint( S.x,S.y );

153         point[ cnt_point ].f = flag++;

154         addpoint( T.x,T.y );//start and end 

155         double x,y1,y2,y3,y4;

156         for( int num=1;num<=m;num++ ){

157             scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);

158             

159             line[ cnt_line ].f = flag;

160             addline( x,0.0,x,y1 );

161             line[ cnt_line ].f = flag;

162             addline( x,y2,x,y3 );

163             line[ cnt_line ].f = flag;

164             addline( x,y4,x,10.0 );//这三条线段归为一类

165             

166             point[ cnt_point ].f = flag;

167             addpoint( x,y1 );

168             point[ cnt_point ].f = flag;

169             addpoint( x,y2 );

170             point[ cnt_point ].f = flag;

171             addpoint( x,y3 );

172             point[ cnt_point ].f = flag;

173             addpoint( x,y4 );//这四个点归为一类

174             

175             flag++;

176         }

177         //printf("flag:%d\ncnt_point:%d\ncnt_line:%d\n",flag,cnt_point,cnt_line);

178         for( int i=0;i<cnt_point;i++ ){

179             for( int j=i+1;j<cnt_point;j++ ){

180                 if( point[ i ].f!=point[ j ].f&&test( point[ i ],point[ j ] )==true ){

181                     mat[ i ][ j ] = mat[ j ][ i ] = dist( point[ i ],point[ j ] );

182                     //printf("mat[ %d ][ %d ] = %.2lf\n",i,j,mat[i][j]);

183                 }

184             }

185         }

186         if( mat[ 0 ][ 1 ]!=inf ){

187             printf("%.2lf\n",mat[ 0 ][ 1 ]);

188             continue;

189         }

190         double ans = dij( 0,1 );

191         printf("%.2lf\n",ans);

192     }

193     return 0;

194 }

哈哈哈哈。。。。代码有点长。。。。。

 

 

你可能感兴趣的:(poj)