poj 3608 Bridge Across Islands 两凸包间最近距离
1 /** 2 旋转卡壳,, 3 **/ 4 #include <iostream> 5 #include <algorithm> 6 #include <cmath> 7 #include <cstdio> 8 using namespace std; 9 10 const double eps = 1e-8; 11 struct point { 12 double x,y; 13 point(double x=0,double y =0):x(x),y(y){} 14 }; 15 16 int dcmp(double x){ 17 if(fabs(x)<eps) 18 return 0; 19 else 20 return x<0?-1:1; 21 } 22 23 point p[10020],p1[10020]; 24 point q[10020],q1[10020]; 25 int maxid,minid; 26 int N,M; 27 typedef point Vector; 28 29 Vector operator -(point a,point b){ 30 return Vector(a.x-b.x,a.y-b.y); 31 } 32 33 double cross(Vector a,Vector b){ 34 return a.x*b.y-a.y*b.x; 35 } 36 37 double dot(Vector a,Vector b){ 38 return a.x*b.x+a.y*b.y; 39 } 40 bool cmp(point a,point b){ 41 if(a.x==b.x) 42 return a.y<b.y; 43 return a.x<b.x; 44 } 45 46 bool operator ==(const point &a,const point &b){ 47 return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; 48 } 49 50 double length(Vector a){ 51 return sqrt(a.x*a.x+a.y*a.y); 52 } 53 54 int convexHull(point *p,int n,point *ch){ 55 sort(p,p+n,cmp); 56 int m =0; 57 for(int i=0;i<n;i++){ 58 while(m>1&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) 59 m--; 60 ch[m++] = p[i]; 61 } 62 int k =m; 63 for(int i = n-2;i>=0;i--){ 64 while(m>k&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) 65 m--; 66 ch[m++] = p[i]; 67 } 68 if(n>1) m--; 69 return m; 70 } 71 72 double distanceToSegment(point p,point a,point b){ 73 if(a==b) 74 return length(p-a); 75 Vector v1 = b-a,v2 = p-a, v3 = p-b; 76 if(dcmp(dot(v1,v2))<0) 77 return length(v2); 78 else if(dcmp(dot(v1,v3))>0) 79 return length(v3); 80 else 81 return fabs(cross(v1,v2))/length(v1); 82 } 83 84 double distanceBetweenSegment(point a,point b,point c,point d){ 85 return min(min(distanceToSegment(a,c,d),distanceToSegment(b,c,d)),min(distanceToSegment(c,a,b),distanceToSegment(d,a,b))); 86 } 87 88 void getMaxAndMin(int &maxid,int &minid){ 89 maxid =0; 90 minid =0; 91 for(int i=1;i<N;i++){ 92 if(p1[i].y<p1[minid].y) 93 minid =i; 94 } 95 for(int i=0;i<M;i++){ 96 if(q1[i].y>q1[maxid].y) 97 maxid = i; 98 } 99 } 100 101 double solve(point *p,point *q,int minid,int maxid,int N,int M){ 102 double temp,ret = 1e5; 103 p[N] = p[0]; 104 q[M] = q[0]; 105 for(int i=0;i<N;i++){ 106 while(temp = dcmp(cross(q[maxid]-q[maxid+1],p[minid+1]-p[minid]))>0){ 107 maxid = (maxid+1)%M; 108 } 109 if(temp<0) 110 ret = min(ret,distanceToSegment(q[maxid],p[minid],p[minid+1])); 111 else 112 ret = min(ret,distanceBetweenSegment(p[minid],p[minid+1],q[maxid],q[maxid+1])); 113 minid = (minid+1)%N; 114 } 115 return ret; 116 } 117 118 int main() 119 { 120 121 while(cin>>N>>M){ 122 if(N==0&&M==0) 123 break; 124 for(int i=0;i<N;i++) 125 cin>>p[i].x>>p[i].y; 126 for(int i=0;i<M;i++) 127 cin>>q[i].x>>q[i].y; 128 N = convexHull(p,N,p1); 129 M = convexHull(q,M,q1); 130 getMaxAndMin(maxid,minid); 131 double ans = solve(p1,q1,minid,maxid,N,M); 132 printf("%.5lf\n",ans); 133 } 134 return 0; 135 }