[poj][3608][Bridge Across Islands]

题目:http://poj.org/problem?id=3608

View Code
#include <stdio.h>

#include <math.h>

#include <string.h>

#include <algorithm>



#define clr(a,b) memset(a,b,sizeof(a))

#define sqr(x) ((x)*(x))

using namespace std;



const double eps = 1e-8;

const double pi = acos(-1.0);

const int inf = 0x3f3f3f3f;

const int N = 10000+10;



int dcmp(double x){

    if (x < -eps) return -1;

    else return x > eps;

}



struct cpoint

{

    double x, y;

    cpoint(){}

    cpoint(double x, double y):x(x), y(y){}

    void get() { scanf("%lf%lf", &x, &y); }

    bool operator == (const cpoint& u)const{

        return dcmp(x - u.x) == 0 && dcmp(y - u.y) == 0;

    }

};



double cross(cpoint o, cpoint p, cpoint q){

    return (p.x-o.x)*(q.y-o.y)-(q.x-o.x)*(p.y-o.y);

}

double dot(cpoint o, cpoint p, cpoint q){

    return (p.x-o.x)*(q.x-o.x)+(p.y-o.y)*(q.y-o.y);

}

double dis(cpoint p, cpoint q){

    return sqrt(sqr(p.x-q.x) + sqr(p.y-q.y));

}

double dissqr(cpoint p, cpoint q){

    return sqr(p.x-q.x) + sqr(p.y-q.y);

}

bool PointOnSegment(cpoint p0, cpoint p1, cpoint p2){

    return dcmp(cross(p0, p1, p2)) == 0 && dcmp(dot(p0, p1, p2)) <= 0;

}

double PointToLine(cpoint p0, cpoint p1, cpoint p2, cpoint &cp){

    double d = dis(p1, p2);

    double s = cross(p1, p2, p0) / d;

    cp.x = p0.x + s * (p2.y - p1.y) / d;

    cp.y = p0.y - s * (p2.x - p1.x) / d;

    return fabs(s);

}

cpoint bp;

int PolarCmp(const cpoint &p1, const cpoint &p2){

    int u = dcmp(cross(bp, p1, p2));

    return u > 0 || (u==0 && dcmp(dissqr(bp, p1)-dissqr(bp, p2))<0);

}

void graham(cpoint pin[], int n, cpoint ch[], int &m){

    int i, j, k, u, v;

    memcpy(ch, pin, n*sizeof(cpoint));

    for (i=k=0; i<n; i++){

        u = dcmp(ch[i].x - ch[k].x);

        v = dcmp(ch[i].y - ch[k].y);

        if (v < 0 || (v==0 && u<0)) k = i;

    }

    bp = ch[k];

    sort(ch, ch+n, PolarCmp);

    n = unique(ch, ch+n) - ch;

    if (n <= 1) { m = n; return ; }

    if (dcmp(cross(ch[0],ch[1],ch[n-1]))==0){

        m = 2; ch[1] = ch[n-1]; return ;

    }

    ch[n++] = ch[0];

    for (i=1, j=2; j<n; j++){

        while (i>0 && dcmp(cross(ch[i-1], ch[i], ch[j]))<=0)i--;

        ch[++i] = ch[j];

    }

    m = i;

}

double PointToSeg(cpoint p0, cpoint p1, cpoint p2){

    cpoint cp;

    double d = PointToLine(p0, p1, p2, cp);

    if (PointOnSegment(cp, p1, p2)) return d;

    else return min(dis(p0, p1), dis(p0, p2));

}

double DisPallSeg(cpoint p0, cpoint p1, cpoint p2, cpoint p3){

    return min(min(PointToSeg(p0, p2, p3), PointToSeg(p1, p2, p3)),

               min(PointToSeg(p2, p0, p1), PointToSeg(p3, p0, p1)));

}

void anticlockwise(cpoint cp[], int n){

    for (int i=0; i<n-2; i++){

        double t = cross(cp[i], cp[i+1], cp[i+2]);

        if (dcmp(t) > 0) return ;

        if (dcmp(t) < 0) { reverse(cp, cp+n); return ; }

    }

}

double rotating(cpoint ch1[], int n, cpoint ch2[], int m){

    int p = 0, q = 0;

    for (int i=0; i<n; i++)

        if (dcmp(ch1[i].y - ch1[p].y) < 0)

            p = i;

    for (int i=0; i<m; i++)

        if (dcmp(ch2[i].y - ch2[q]. y) > 0)

            q = i;

    ch1[n] = ch1[0], ch2[m] = ch2[0];

    double tmp, res = 1e99;

    for (int i=0; i<n; i++){

        while ((tmp = cross(ch1[p],ch1[p+1],ch2[q+1])-

            cross(ch1[p],ch1[p+1],ch2[q])) > eps)

            q = (q + 1) % m;

        if (dcmp(tmp) < 0) res = min(res, PointToSeg(ch2[q], ch1[p], ch1[p+1]));

        else res = min(res, DisPallSeg(ch1[p], ch1[p+1], ch2[q], ch2[q+1]));

        p = (p + 1) % m;

    }

    return res;

}



void solve(cpoint ch1[], int n, cpoint ch2[], int m){

    anticlockwise(ch1, n);

    anticlockwise(ch2, m);

    double ans = min(rotating(ch1, n, ch2, m), rotating(ch2, m, ch1, n));

    printf("%.5f\n", ans);

}

cpoint p[N], q[N];

int main()

{

    //freopen("D:/a.txt", "r", stdin);

    int n, m;

    while (~scanf("%d%d", &n, &m))

    {

        if (n==0 && m==0) break;

        for (int i=0; i<n; i++) p[i].get();

        for (int i=0; i<m; i++) q[i].get();

        solve(p, n, q, m);

    }

    return 0;

}

你可能感兴趣的:(bridge)