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 }
View Code

 

posted @ 2017-10-19 21:06  yijiull  阅读(232)  评论(0编辑  收藏  举报