Bridge Across Islands POJ - 3608(凸包最近距离)
Bridge Across Islands
POJ - 3608题意:求凸包最近距离.
旋转卡壳~
转自:Gitfan
1 #include <bits/stdc++.h> 2 using namespace std; 3 const double eps = 1e-8; 4 const int inf = 0x3f3f3f3f; 5 const int maxn = 10010; 6 7 struct Point{ 8 double x, y; 9 Point(double x = 0, double y = 0): x(x), y(y){} 10 }; 11 typedef Point Vector; 12 13 Vector operator - (Point a, Point b) { 14 return Vector(a.x - b.x, a.y - b.y); 15 } 16 Vector operator + (Vector a, Vector b) { 17 return Vector(a.x + b.x, a.y + b.y); 18 } 19 Vector operator * (Vector a, double p) { 20 return Vector(a.x * p, a.y * p); 21 } 22 Vector operator / (Vector a, double p) { 23 return Vector(a.x / p, a.y / p); 24 } 25 bool operator < (Point a, Point b) { 26 return a.x < b.x || a.x == b.x && a.y < b.y; 27 } 28 int dcmp(double x) { 29 if(fabs(x) < eps) return 0; 30 return x < 0 ? -1 : 1; 31 } 32 33 bool operator == (Point a, Point b) { 34 return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; 35 } 36 double Dot(Vector a, Vector b) { 37 return a.x * b.x + a.y * b.y; 38 } 39 double Cross(Vector a, Vector b) { 40 return a.x * b.y - a.y * b.x; 41 } 42 double Length(Vector a) { 43 return sqrt(Dot(a, a)); 44 } 45 double Angle(Vector a) { 46 return atan2(a.y, a.x); 47 } 48 double DistanceToSegment(Point p, Point a, Point b) { 49 if(a == b) return Length(p-a); 50 Vector v1 = b - a, v2 = p - a, v3 = p - b; 51 if(dcmp(Dot(v1, v2)) < 0) return Length(v2); 52 if(dcmp(Dot(v1, v3)) > 0) return Length(v3); 53 return fabs(Cross(v1, v2)) / Length(v1); 54 } 55 double SegmentDistance(Point a1, Point b1, Point a2, Point b2) { 56 return min(min(DistanceToSegment(a1, a2, b2), DistanceToSegment(b1, a2, b2)), 57 min(DistanceToSegment(a2, a1, b1), DistanceToSegment(b2, a1, b1))); 58 } 59 //两凸包的最短距离 60 double RotateCalipers(Point *p1, int n, Point *p2, int m) { 61 int minp1 = 0, maxp2 = 0; 62 for(int i = 0; i < n; i++){ 63 if(p1[i].y < p1[minp1].y) minp1 = i; 64 } 65 for(int i = 0; i < m; i++){ 66 if(p2[i].y > p2[maxp2].y) maxp2 = i; 67 } 68 p1[n] = p1[0]; 69 p2[m] = p2[0]; 70 double dis = inf, temp; 71 for(int i = 0; i < n; i++) { 72 while(dcmp(Cross(p1[minp1] - p1[minp1+1], p2[maxp2+1] - p1[minp1+1]) - Cross(p1[minp1] - p1[minp1+1], p2[maxp2] - p1[minp1+1])) < 0) maxp2 = (maxp2+1) % m; 73 dis = min(dis, SegmentDistance(p1[minp1], p1[minp1+1], p2[maxp2], p2[maxp2+1])); 74 minp1 = (minp1+1) % n; 75 } 76 return dis; 77 } 78 Point p1[maxn], p2[maxn]; 79 int main(){ 80 int n, m; 81 //freopen("in.txt", "r", stdin); 82 while(scanf("%d %d", &n, &m) && (n+m)) { 83 for(int i = 0; i < n; i++){ 84 scanf("%lf %lf", &p1[i].x, &p1[i].y); 85 } 86 for(int i = 0; i < m; i++){ 87 scanf("%lf %lf", &p2[i].x, &p2[i].y); 88 } 89 printf("%lf\n", RotateCalipers(p1, n, p2, m)); 90 } 91 return 0; 92 }