inblog logo
|
stupefyee
    기술정리

    Union-Find (서로소 집합)

    Stupefyee's avatar
    Stupefyee
    Jul 07, 2025
    Union-Find (서로소 집합)
    Contents
    1. 주요 연산2. 초기화3. 사용 예시4. 시간 복잡도5. 비유로 이해하기
    💡
    여러 개의 집합을 효율적으로 관리하기 위한 자료구조
    • 주로 네트워크 연결, 군집화, 최소 스패닝 트리, 시간/날짜 예약 처리 등에 사용
    • 핵심 연산은 두 가지:
      • find(x): x가 속한 집합의 대표(루트)를 찾기
      • union(x, y): x와 y가 속한 집합을 하나로 합치기

    1. 주요 연산

    find(x)

    • x가 속한 집합의 대표 노드를 반환해요.
    • *경로 압축(Path Compression)**을 사용하면, 트리 구조가 납작해져서 성능이 좋아져요.
    int find(int[] parent, int x) { if (parent[x] != x) { parent[x] = find(parent, parent[x]); // 경로 압축 } return parent[x]; }

    union(x, y)

    • x와 y가 속한 집합을 하나의 집합으로 합쳐요.
    • 루트를 기준으로 병합하며, 효율을 위해 랭크(rank) 또는 크기(size)를 고려하기도 해요.
    void union(int[] parent, int x, int y) { int px = find(parent, x); int py = find(parent, y); if (px != py) { parent[py] = px; // py의 루트를 px로 병합 } }

    2. 초기화

    • 각 원소는 자기 자신이 루트로 시작해요.
    int[] parent = new int[n + 1]; for (int i = 0; i <= n; i++) { parent[i] = i; }

    3. 사용 예시

    네트워크 연결 여부 확인

    if (find(a) == find(b)) { // 같은 집합에 속해 있음 (연결되어 있음) }

    4. 시간 복잡도

    • 암묵적인 경로 압축 + union by rank/size를 사용할 경우
    • 거의 O(1)에 가까운 성능 (정확히는 O(α(N)), 역 아커만 함수)

    5. 비유로 이해하기

    • 각각의 사람(노드)은 조장을 가리키고 있음
    • find()는 궁극적으로 조장이 누군지 알아내는 과정
    • union()은 두 반을 합쳐서 같은 조장을 갖게 만드는 과정
    Share article
    Contents
    1. 주요 연산2. 초기화3. 사용 예시4. 시간 복잡도5. 비유로 이해하기

    stupefyee

    RSS·Powered by Inblog