poj1556(线段相交模板题)

求(0,5) 到(10,5)的最短距离

对每两个点进行建边然后跑最短路

判断线段相交的方法参考这个博客:快速排斥实验和跨立实验

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int mx = 105;
int n;
double mat[mx][mx];

struct Point {
    double x, y;
    Point () {}
    Point (double _x, double _y) {
        x = _x; y = _y;
    }
}pt[mx];

struct Line {
    double x1, y1, x2, y2;
    Line () {}
    Line (double _x1, double _y1, double _x2, double _y2) {
        x1 = _x1; x2 = _x2; y1 = _y1; y2 = _y2;
    }
}le[mx];

double dis(Point a, Point b) {
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

double cross(double x1, double y1, double x2, double y2) {
    return x1*y2 - x2*y1;
}

bool judge(Point a, Point b) {
    for (int i = 1; i <= n*3; i++) {
        if (cross(le[i].x1-a.x,le[i].y1-a.y,b.x-a.x,b.y-a.y) *
            cross(b.x-a.x,b.y-a.y,le[i].x2-a.x,le[i].y2-a.y) > eps
            && cross(a.x-le[i].x2,a.y-le[i].y2,le[i].x1-le[i].x2,le[i].y1-le[i].y2) *
            cross(le[i].x1-le[i].x2,le[i].y1-le[i].y2,b.x-le[i].x2,b.y-le[i].y2) > eps)
                return false;
    }
    return true;
}

void init() {
    for (int i = 0; i < mx; i++)
        for (int j = 0; j < mx; j++)
            mat[i][j] = INF;
}

int main() {
    while (scanf("%d",&n) != EOF && n != -1) {
        init();
        double a, b, c, d, e;
        for (int i = 1; i <= n; i++) {
            scanf("%lf%lf%lf%lf%lf",&a, &b, &c, &d, &e);
            pt[i*4-3] = Point(a, b);
            pt[i*4-2] = Point(a, c);
            pt[i*4-1] = Point(a, d);
            pt[i*4-0] = Point(a, e);
            le[i*3-2] = Line(a, 0, a, b);
            le[i*3-1] = Line(a, c, a, d);
            le[i*3-0] = Line(a, e, a, 10);
        }
        pt[n*4+1] = Point(0, 5); pt[n*4+2] = Point(10, 5);
        for (int i = 1; i <= n*4+2; i++) {
            for (int j = i+1; j <= n*4+2; j++) {
                if (abs(pt[i].x-pt[j].x) < eps) continue;
                if (judge(pt[i], pt[j])) {
                    //printf("%f %f %f %f --- %f\n",pt[i].x, pt[i].y, pt[j].x, pt[j].y,abs(pt[i].x-pt[j].x));
                    mat[i][j] = mat[j][i] = dis(pt[i],pt[j]);
                }
            }
        }
        for (int k = 1; k <= 4*n+2; k++) {
            for (int i = 1; i <= 4*n+2; i++) {
                for (int j = 1; j <= 4*n+2; j++) {
                    mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]);
                }
            }
        }
        printf("%.2f\n", mat[4*n+1][4*n+2]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/bpdwn2017/article/details/81561330
今日推荐