Skip to content

Latest commit

Β 

History

History
176 lines (144 loc) Β· 5.25 KB

README.md

File metadata and controls

176 lines (144 loc) Β· 5.25 KB

Union Find

μœ λ‹ˆμ˜¨ νŒŒμΈλ“œλž€ Disjoint Setλ₯Ό ν‘œν˜„ν•  λ•Œ μ‚¬μš©ν•˜λŠ” κ·Έλž˜ν”„ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ,
두 λ…Έλ“œκ°€ 같은 κ·Έλž˜ν”„μ— μ†ν•˜λŠ”μ§€ νŒλ³„ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μž…λ‹ˆλ‹€.
λ…Έλ“œλ₯Ό ν•©μΉ˜λŠ” Union μ—°μ‚°κ³Ό, λ…Έλ“œμ˜ 루트 λ…Έλ“œλ₯Ό μ°ΎλŠ” Find μ—°μ‚°μœΌλ‘œ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

πŸ’‘ Disjoint Set
Disjoint Setμ΄λž€ μ„œλ‘œμ†Œ 집합 자료ꡬ쑰둜,
μ„œλ‘œ μ€‘λ³΅λ˜μ§€ μ•ŠλŠ” λΆ€λΆ„ μ§‘ν•©λ“€λ‘œ λ‚˜λˆ μ§„ μ›μ†Œλ“€μ— λŒ€ν•œ 정보λ₯Ό μ €μž₯ν•˜κ³  μ‘°μž‘ν•˜λŠ” μžλ£Œκ΅¬μ‘°μž…λ‹ˆλ‹€.
즉, 곡톡 μ›μ†Œκ°€ μ—†λŠ” μƒν˜Έ 배타적인 λΆ€λΆ„ μ§‘ν•©λ“€λ‘œ λ‚˜λˆ μ§„ μ›μ†Œλ“€μ— λŒ€ν•œ μžλ£Œκ΅¬μ‘°μž…λ‹ˆλ‹€.

1. init

졜초 λ…Έλ“œλŠ” 자기 μžμ‹ μ„ 루트 λ…Έλ“œλ‘œ 가지도둝 μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.

for (int i = 0; i < parent.length; i++)
    parent[i] = i;

2. find(x)

xκ°€ μ†ν•œ κ·Έλž˜ν”„μ˜ root λ…Έλ“œλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.

static int find(int x) {
    if (x == parent[x]) return x; // xκ°€ λ£¨νŠΈλ…Έλ“œμΌ 경우 λ°˜ν™˜
    int nx = find(parent[x]); // μ΅œμƒμœ„ λ…Έλ“œλ₯Ό μ°ΎλŠ” κ³Όμ •μ—μ„œ 경둜 μ΅œμ ν™”
    parent[x] = nx;
    return nx;
}

경둜 μ΅œμ ν™”λ₯Ό μ§„ν–‰ν•˜μ§€ μ•Šμ„ 경우, 사ν–₯ 트리(Skewed Tree)일 λ•Œ μ‹œκ°„ λ³΅μž‘λ„λŠ” O(n)이 λ©λ‹ˆλ‹€.
경둜 압좕을 ν•˜κ²Œ 되면, 맀번 트리의 높이가 λ‹¬λΌμ§€κ²Œ λ˜λ―€λ‘œ μ‹œκ°„ λ³΅μž‘λ„λŠ” O(a(n))이 λ©λ‹ˆλ‹€.
> μ—¬κΈ°μ„œ a(N)은 μ•„μ»€λ§Œ ν•¨μˆ˜λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

μ•„μ»€λ§Œ ν•¨μˆ˜

μ•„μ»€λ§Œ ν•¨μˆ˜λž€ μ›μ‹œ μž¬κ·€ ν•¨μˆ˜κ°€ μ•„λ‹Œ 전역적인 μž¬κ·€ ν•¨μˆ˜μž…λ‹ˆλ‹€.

이 값은 μž…λ ₯이 μž‘λ”λΌλ„ 맀우 λΉ λ₯΄κ²Œ μ¦κ°€ν•˜μ—¬, N이 2^65536일 λ•Œ, μ•„μ»€λ§Œ ν•¨μˆ˜μ˜ 값은 5κ°€ λ˜λ―€λ‘œ μƒμˆ˜μ˜ μ‹œκ°„ λ³΅μž‘λ„λ₯Ό 가진닀고 봐도 λ¬΄λ°©ν•©λ‹ˆλ‹€.

3. union(x, y)

xκ°€ μ†ν•œ κ·Έλž˜ν”„μ™€ yκ°€ μ†ν•œ κ·Έλž˜ν”„λ₯Ό ν•©μΉ©λ‹ˆλ‹€.

static void union(int x, int y) {
    x = find(x);
    y = find(y);
    
    if (x == y) return;
    parent[y] = x
}

같은 λΆ€λͺ¨ λ…Έλ“œλ₯Ό κ°€μ§€λŠ”μ§€ ν™•μΈν•˜λŠ” ν•¨μˆ˜

static boolean isSameParent(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return true;
    else return false;
}

μ½”λ“œ

λ°±μ€€ 1976번 μ—¬ν–‰ κ°€μž

import java.io.*;
import java.util.*;
public class Main {

    static int[] parent;
    static int find(int x) {
        if (parent[x] == x) return x;
        return parent[x] = find(parent[x]);
    }

    static void union(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        else parent[y] = x;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int N = Integer.parseInt(br.readLine());
        int M = Integer.parseInt(br.readLine());
        int connect;
        parent = new int[N + 1];
        for (int i = 1; i <= N; i++) parent[i] = i;

        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= N; j++) {
                connect = Integer.parseInt(st.nextToken());
                if (connect == 1) union(i, j);
            }
        }

        int[] path = new int[M];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < M; i++) path[i] = Integer.parseInt(st.nextToken());
        boolean isAvailable = true;

        int root = find(path[0]);
        for (int i = 1; i < M; i++) {
            if (root != find(path[i])) { isAvailable = false; break; }
        }

        if (isAvailable) System.out.println("YES");
        else System.out.println("NO");
        br.close();
    }
}

λ°±μ€€ 4195번 친ꡬ λ„€νŠΈμ›Œν¬

import java.io.*;
import java.util.*;

public class Main {

    static Map<String, String> parent;
    static Map<String, Integer> cnt;

    static String find(String x) {
        if (parent.get(x) == x) return x;
        String nx = find(parent.get(x));
        parent.put(x, nx);
        return nx;
    }

    static void union(String x, String y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        parent.put(y, x);
        cnt.put(x, cnt.get(x) + cnt.get(y));
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());
        int N;
        String x, y;

        for (int t = 0; t < T; t++) {
            parent = new HashMap<>();
            cnt = new HashMap<>();
            N = Integer.parseInt(br.readLine());

            for (int i = 0; i < N; i++) {
                st = new StringTokenizer(br.readLine());
                x = st.nextToken();
                y = st.nextToken();
                if (!parent.containsKey(x)) { parent.put(x, x); cnt.put(x, 1); }
                if (!parent.containsKey(y)) { parent.put(y, y); cnt.put(y, 1); }
                union(x, y);
                sb.append(cnt.get(find(x))).append("\n");
            }
        }

        System.out.println(sb);
        br.close();
    }
}