Taaewoo
Data Engineering Blog
Taaewoo
전체 방문자
오늘
어제
  • 분류 전체보기 (67)
    • Computer Science (16)
      • Algorithm (6)
      • OS (1)
      • Java (2)
      • C++ (6)
      • Python (1)
    • Hadoop Ecosystem (27)
      • Hadoop (6)
      • Spark (5)
      • NiFi (6)
      • Hive (9)
      • Kafka (1)
    • BigData Engineering (14)
      • Jupyter (1)
      • Docker (3)
      • CDH (3)
      • Riot Data Pipeline (7)
    • Back-end 개발 (0)
      • Spring (0)
    • Algorithm 문제 풀이 (9)
      • 백준 (5)
      • LeetCode (4)
    • Conference (1)
      • LINE DEVELOPER DAY 2021 (1)
      • if(kakao) 2021 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 빅데이터
  • hadoop
  • 프로그래밍
  • sort
  • Hive
  • spark
  • 정렬
  • kafka
  • algorithm
  • 알고리즘
  • Coding
  • docker
  • 코딩
  • CS
  • hdfs
  • C++
  • metastore
  • java
  • NiFi
  • BigData

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Taaewoo

Data Engineering Blog

[Algorithm][Union Find] 백준 1717 - 집합의 표현
Algorithm 문제 풀이/백준

[Algorithm][Union Find] 백준 1717 - 집합의 표현

2021. 10. 8. 03:37

알고리즘 분류

 Union Find

 

시간 복잡도

 \( O(N) \)

 

문제 링크

https://www.acmicpc.net/problem/1717


 이번 문제의 알고리즘 종류는 Union Find입니다. 많은 수가 있을 때 특정 수들이 같은 집합인가?라는 물음에 대해 효율적으로 사용할 수 있는 알고리즘입니다. Union Find의 핵심은 "같은 집합이면 같은 루트"입니다. 처음에는 모든 수들이 자기 자신을 루트로 가지고 있도록 초기화를 시켜놓습니다. 하지만 두 수를 merge 한다면 각 수의 루트 값들이 부모, 자식의 관계를 가지게 됩니다. ( 아래 예시를 보면 이해가 가능합니다. ) 그리고 서로 같은 집합임을 알고싶다면 각 숫자들의 최상단 부모, 즉 루트 값을 비교할 수 있습니다.

 

 하지만 이렇게 계속 진행하다보면 1 -> 2 -> 3 -> 4 -> 5 -> 6 이런 식으로 줄지어서 부모를 가지게 되는 최악의 경우의 수가 있습니다. 이런 경우 1이라는 숫자는 최상단 루트의 값을 알기 위해서는 총  \( N-1 \)번의 연산이 필요합니다. 그러면 결국  \( N \)개 수의 대해서 최악의 경우 시간 복잡도는  \( O(N^2) \)를 가지게 되므로 N이 10만 이상이라면 시간 초과가 발생할 것입니다.

 

 그래서 위에서 핵심을 말했듯이 서로 같은 집합에 속해있다면 각 수들은 루트만 기억하도록 하는 것입니다. 그러면 모든 수는 자신의 루트를 찾는데  \( O(1) \)의 시간이 걸리게 함으로써 더욱 빠른 시간복잡도를 가지게 됩니다. 참고로 최상단 부모, 즉 루트 값은 find 함수가 호출되는 시점에 업데이트가 됩니다.

 

이번 문제는 Union Find의 가장 기본적인 문제입니다. Union Find의 문제는 merge와 find만 구현하면 거의 다 해결했다고 볼 수 있습니다. 아래의 예시는 1 ~ 7의 숫자들이 여러 과정의 merge가 이루어지는 결과를 보여줍니다. (  마지막 예시인 7과 5가 merge 될 때 7은 이 시점에서 루트 값을 업데이트합니다. )

 

 

Java

import java.util.*;

public class Main {

    static int[] p = new int[1000001];

    public static int find(int n){
        if(p[n] == n) return n;
        return p[n] = find(p[n]);
    }

    public static void merge(int a, int b){
        a = find(a);
        b = find(b);
        if(a==b) return;
        p[b] = a;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();

        for(int i=1; i<=n; i++)
            p[i] = i;

        for(int i=0, t,a,b; i<m; i++){
            t = sc.nextInt();
            a = sc.nextInt();
            b = sc.nextInt();

            if(t == 0) merge(a,b);
            else if(t==1) System.out.println((find(a)==find(b)) ? "YES" : "NO");
        }
    }
}
저작자표시 비영리 (새창열림)

'Algorithm 문제 풀이 > 백준' 카테고리의 다른 글

[Algorithm][투 포인터] 백준 1806 - 부분합  (0) 2021.10.06
[Algorithm][BFS] 백준 13549 - 숨바꼭질 3  (0) 2021.10.04
[Algorithm][부분 합] 백준 11659 - 구간 합 구하기 4  (0) 2021.09.29
[Algorithm][위상 정렬] 백준 2252 - 줄 세우기  (0) 2021.09.28
    'Algorithm 문제 풀이/백준' 카테고리의 다른 글
    • [Algorithm][투 포인터] 백준 1806 - 부분합
    • [Algorithm][BFS] 백준 13549 - 숨바꼭질 3
    • [Algorithm][부분 합] 백준 11659 - 구간 합 구하기 4
    • [Algorithm][위상 정렬] 백준 2252 - 줄 세우기
    Taaewoo
    Taaewoo

    티스토리툴바