POJ - 1127 -- Jack Straws

题目来源:http://poj.org/problem?id=1127

判定线段相交+floyd。

判定线段相交的模板来自《算法导论》P597。

使用floyd处理出所有传递闭包(类似并查集,floyd更好写一些)。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
const double eps=1e-7;
int n;
struct Point {
    double x, y;
} l[20], r[20];
int g[20][20];

double direction(Point p0, Point p2, Point p1) {
    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

bool on_segment(Point pi, Point pj, Point pk) {
    if (min(pi.x, pj.x) <= pk.x && pk.x <= max(pi.x, pj.x) &&
        min(pi.y, pj.y) <= pk.y && pk.y <= max(pi.y, pj.y))
        return 1;
    return 0;
}

bool segments_intersect(Point p1, Point p2, Point p3, Point p4) {
    double d1 = direction(p3, p4, p1);
    double d2 = direction(p3, p4, p2);
    double d3 = direction(p1, p2, p3);
    double d4 = direction(p1, p2, p4);
    if (((d1 > 0.0 && d2 < 0.0) || (d1 < 0.0 && d2 > 0.0)) &&
        ((d3 > 0.0 && d4 < 0.0) || (d3 < 0.0 && d4 > 0.0)))
        return 1;
    if (fabs(d1) < eps && on_segment(p3, p4, p1))
        return 1;
    if (fabs(d2) < eps && on_segment(p3, p4, p2))
        return 1;
    if (fabs(d3) < eps && on_segment(p1, p2, p3))
        return 1;
    if (fabs(d4) < eps && on_segment(p1, p2, p4))
        return 1;
    return 0;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    while (cin >> n) {
        if (n == 0)break;
        for (int i = 1; i <= n; ++i)
            cin >> l[i].x >> l[i].y >> r[i].x >> r[i].y;
        memset(g, 0, sizeof(g));
        for (int i = 1; i <= n; ++i) {
            for (int j = i; j <= n; ++j) {
                if (i == j)
                    g[i][i] = 1;
                else if (segments_intersect(l[i], r[i], l[j], r[j]))
                    g[i][j] = g[j][i] = 1;
            }
        }
        for (int k = 1; k <= n; ++k) {
            for (int i = 1; i <= n; ++i) {
                for (int j = 1; j <= n; ++j) {
                    g[i][j] = g[i][j] | (g[i][k] & g[k][j]);
                }
            }
        }
        int x, y;
        while (cin >> x >> y) {
            if (x == 0)break;
            if (g[x][y])
                cout << "CONNECTED" << endl;
            else
                cout << "NOT CONNECTED" << endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/moon_sky1999/article/details/81410257