题目来源: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;
}