본문 바로가기
알고리즘

BOJ 10216 - Count Circle Groups(C++)

by 장중앙 2021. 8. 16.

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

댓글