注意:
注意判断两点是否能相连,需要判断这两点之间是否含有其他的线段。。。
同一列的墙 我用的是flag来标记。。
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 }
哈哈哈哈。。。。代码有点长。。。。。