POJ 1127 - Jack Straws
http://poj.org/problem?id=1127
概要
n 本のわらが二次元座標上に置かれている. このとき,いくつかの「a 本目のわらと b 本目のわらが繋がっているか」というクエリに答える.
わらは間接的に繋がっていることもある. つまり,わら a, b, c について,a と b が繋がっていて b と c が繋がっているとき,a と c も繋がっている.
制約
- 1 < n < 13
- 座標は100未満の正の整数値
- 長さが 0 のわらは無い
解法
線分の交差判定 + Union-Find.
線分の交差判定を間違えて 1WA してしまった (線分同士が同一直線上でかつ交わっていないケースを忘れていた).
poj/1127.cc1 #include <iostream> 2 #include <vector> 3 #include <complex> 4 using namespace std; 5 typedef complex<int> P; 6 7 class DisjointSet/*{{{*/ 8 { 9 private: 10 vector<int> parent; 11 12 int root(int x) 13 { 14 if (parent[x] < 0) { 15 return x; 16 } else { 17 parent[x] = root(parent[x]); 18 return parent[x]; 19 } 20 } 21 22 public: 23 explicit DisjointSet(int n) : parent(n, -1) {} 24 25 bool unite(int x, int y) 26 { 27 const int a = root(x); 28 const int b = root(y); 29 if (a != b) { 30 if (parent[a] < parent[b]) { 31 parent[a] += parent[b]; 32 parent[b] = a; 33 } else { 34 parent[b] += parent[a]; 35 parent[a] = b; 36 } 37 return true; 38 } else { 39 return false; 40 } 41 } 42 43 bool find(int x, int y) { return root(x) == root(y); } 44 int size(int x) { return -parent[root(x)]; } 45 };/*}}}*/ 46 47 inline int cross(const P& a, const P& b) { return a.real()*b.imag() - b.real()*a.imag(); } 48 49 struct segment 50 { 51 P a, b; 52 segment() {} 53 segment(const P& x, const P& y) : a(x), b(y) {} 54 55 inline bool intersects(const segment& seg) const 56 { 57 return 58 max(a.real(), b.real()) >= min(seg.a.real(), seg.b.real()) 59 && max(seg.a.real(), seg.b.real()) >= min(a.real(), b.real()) 60 && max(a.imag(), b.imag()) >= min(seg.a.imag(), seg.b.imag()) 61 && max(seg.a.imag(), seg.b.imag()) >= min(a.imag(), b.imag()) 62 && cross(seg.b - seg.a, a - seg.a) * cross(seg.b - seg.a, b - seg.a) <= 0 63 && cross(b - a, seg.a - a) * cross(b - a, seg.b - a) <= 0; 64 } 65 }; 66 67 int main() 68 { 69 int N; 70 while (cin >> N && N != 0) { 71 vector<segment> segs; 72 for (int i = 0; i < N; i++) { 73 int x1, y1, x2, y2; 74 cin >> x1 >> y1 >> x2 >> y2; 75 segs.push_back(segment(P(x1, y1), P(x2, y2))); 76 } 77 DisjointSet s(N); 78 for (int i = 0; i < N; i++) { 79 for (int j = 0; j < i; j++) { 80 if (segs[i].intersects(segs[j])) { 81 s.unite(i, j); 82 } 83 } 84 } 85 86 int a, b; 87 while (cin >> a >> b && !(a == 0 && b == 0)) { 88 --a; --b; 89 cout << (s.find(a, b) ? "" : "NOT ") << "CONNECTED" << endl; 90 } 91 } 92 return 0; 93 }