https://www.acmicpc.net/problem/10216
10216번: Count Circle Groups
백준이는 국방의 의무를 수행하기 위해 떠났다. 혹독한 훈련을 무사히 마치고 나서, 정말 잘 생겼고 코딩도 잘하는 백준은 그 특기를 살려 적군의 진영을 수학적으로 분석하는 일을 맡게 되었
www.acmicpc.net
풀이
노드별 거리 비교를 위한 2중 for문
통신 가능 확인 (p1.x-p2.x)² + (p1.y-p2.y)² <= (r1+r2)²
통신가능 지역이라면 merge(작은값이 부모가 되도록, 2개의 노드가 합쳐지므로 ans--)
#include <iostream> #include <cstring> #include <cmath> using namespace std; int T, N; struct Point { int y, x, r; }; Point point[3001]; int parent[3001]; int find(int now) { if (now == parent[now])return now; return parent[now] = find(parent[now]); } bool check(int i, int j) {//통신영역 확인 Point p1 = point[i]; Point p2 = point[j]; return pow(p1.y - p2.y, 2) + pow(p1.x - p2.x, 2) <= pow(p1.r + p2.r, 2); } void merge(int i, int j) { int pi = find(i); int pj = find(j); if (pj < pi) swap(pi, pj); parent[pj] = pi; } int main() { cin >> T; for (int _ = 0; _ < T; _++) {//테스트 케이스 수 cin >> N; int ans = N; int X, Y, R; memset(parent, -1, sizeof(parent)); for (int idx = 0; idx < N; idx++) {//진영의 수 cin >> X >> Y >> R; point[idx] = { Y,X,R }; parent[idx] = idx; } for (int i = 0; i < N-1; i++) {//union find for (int j = i+1; j < N; j++) { if (find(i) == find(j))continue; if (check(i, j)) { merge(i, j); ans--; } } } cout << ans << endl; } return 0; }
'알고리즘' 카테고리의 다른 글
Programmers - 광고삽입(C++) (0) | 2021.08.24 |
---|---|
BOJ 1405 - 미친로봇(C++) (0) | 2021.08.24 |
Programmers - 외벽점검(C++) (0) | 2021.08.20 |
BOJ 21608 - 상어초등학교(C++) (0) | 2021.08.19 |
Programmers - 다단계 칫솔 판매(C++) (0) | 2021.08.17 |
댓글