[BOJ] 선분 그룹
Date:
[BOJ] 선분 그룹
Problem URL : 선분 그룹
#include <iostream>
#include <algorithm>
#define p pair<int,int>
#define line pair<p,p>
using namespace std;
int n, group[3001], cnt[3001];
line lines[3001];
int ccw(p a, p b, p c) {
int r = a.first * b.second + b.first * c.second + c.first * a.second;
r -= a.second * b.first + b.second * c.first + c.second * a.first;
if (r > 0) return 1;
if (r < 0) return -1;
return 0;
}
int iscross(p a, p b, p c, p d) {
int r1 = ccw(a, b, c) * ccw(a, b, d);
int r2 = ccw(c, d, a) * ccw(c, d, b);
if (r1 == 0 && r2 == 0) {
return !(max(a, b) < min(c, d) || max(c, d) < min(a, b));
}
return r1 <= 0 && r2 <= 0;
}
int find(int u) {
if (u == group[u]) return u;
return group[u] = find(group[u]);
}
void merge(int u, int v) {
u = find(u), v = find(v);
if (u > v) swap(u, v);
group[u] = v;
cnt[v] += cnt[u];
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> lines[i].first.first >> lines[i].first.second >> lines[i].second.first >> lines[i].second.second;
group[i] = i;
cnt[i] = 1;
}
int groupNum = n;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
if (iscross(lines[i].first, lines[i].second, lines[j].first, lines[j].second)) {
int u = find(i), v = find(j);
if (u != v) {
merge(u, v);
groupNum--;
}
}
}
}
int maxCnt = 0;
for (int i = 1; i <= n; i++) {
maxCnt = max(maxCnt, cnt[i]);
}
cout << groupNum << endl << maxCnt;
return 0;
}
Comments
CCW와 선분 교차 관련 알고리즘은 링크를 참조하자
댓글