[그래프/트리 - 응용] Union-Find / 서로소 집합

2023. 1. 10. 14:38·Algorithm/응용

Union-Find란?


백준 문제를 풀 때 DFS로 풀었던 문제를 다른 사람들은 Union-Find로 풀었길래 정리.

 

 

11724번: 연결 요소의 개수

첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. (1 ≤ N ≤ 1,000, 0 ≤ M ≤ N×(N-1)/2) 둘째 줄부터 M개의 줄에 간선의 양 끝점 u와 v가 주어진다. (1 ≤ u, v ≤ N, u ≠ v) 같은 간선은 한 번만 주

www.acmicpc.net

 

 

 

Union-Find 알고리즘

  • 대표적 그래프/트리 알고리즘으로 '합집합 찾기'라는 의미를 가지고 있다.
  • 상호 배타적 집합(Disjoint-set)이라고도 하며 서로소 집합으로 불린다.
    • 서로소인 부분 집합의 표현
  • 여러 노드가 존재할 때, 두 개의 노드를 선택해서, 현재 두 노드가 서로 같은 그래프에 속하는지 판별하는 알고리즘이다.
  • 2가지 연산으로 이루어져 있다.
    • Find : x가 어떤 집합(그래프)에 포함되어 있는지 찾는 연산.
    • Union: x와 y가 포함되어 있는 집합을 합치는 연산
      • 원소 x와 y를 합친다는 뜻은 x와 y의 부모를 같은 원소로 만든다는 것이다.

 

 

Union-Find 예시


 

위와 같이, 모두 연결되어 있지 않고 각자 자기 자신만을 집합의 원소로 가지고 있을 때, 모든 값이 자기 자신을 가리키도록 만든다.

  • i : 노드 번호
  • Parent[i] : i가 어떤 부모 노드에 속해 있는 

즉, 자기 자신이 어떤 부모에 포함되어 있는지를 의미한다.

Parent[i] = i로 표현할 수 있다.

 

 

 

Union(1,2); Union(3,4) 를 해주어 위와 같이 노드를 연결해보자.

위와 같이 표에 표현이 된다. 2번째 인덱스에 '1'이 들어가고, 4번 인덱스에 '3'이 들어가는 것으로 각각의 부모 인덱스를 갖고 있다.

  • parent[2] = 1
  • parent[4] = 3

이와 같이 부모를 합칠 때는 일반적으로 노드 번호가 작은 쪽이 부모가 되도록 한다. 이것을 Union 과정이라고 한다.

 

 

또 다른 예시로 위와 같이 1, 2, 3이 연결될 때는 바로 아래와 같이 표현이 된다.

 

1과 3은 부모가 다르기 때문에 '1과 3이 연결되었는지' 파악하기 힘들다. 이는 재귀함수가 사용된다.

3의 부모인 2를 먼저 찾고, 2의 부모인 1을 찾아, 결과적으로 3의 부모는 1이 되는 것을 파악하는 것이다.

  • parent[3] = find(parent[3]) . 이때 parent[3] == 2이므로 find(2).
  • parent[2] = find(parent[2]) . 이때 parent[2] == 1이므로 find(1).
  • find(1)은 1을 갖고 있기 때문에 결국 재귀적으로 parent[3] = 1이 된다.

Union(1,3)의 과정이 수행된 후에는 다음과 같은 표가 된다.

 

 

결국 1,2,3의 부모는 모두 1이기 때문에 이 세 가지 노드는 모두 같은 그래프에 속한다는 것을 알 수 있습니다.

해당 경로를 바꿔주는 과정은 아래와 같은 그림으로 변하게 됩니다.

 

 

 

Union-Find 함수


find 함수의 소스코드

1
2
3
4
5
6
public static int find(int x) {
       if(parent[x] == x)
           return x;
       else
          return parent[x] = find(parent[x]);
}
Colored by Color Scripter
cs

find 함수는 매개변수로 받은 원소 x의 부모 노드가 누구인지를 찾아주는 함수이다. 만약 x의 부모가 x이라면 그대로 x를 리턴하면 된다. 만약 아니라면 x의 부모를 다시 find 함수에 보내 재귀 호출을 하여 x의 부모를 찾게 된다.

 

 

union 함수의 소스코드

1
2
3
4
5
6
7
8
9
10
11
public static boolean union(int x, int y) {
    x = find(x); //x의 부모노드 찾기
    y = find(y); //y의 부모노드 찾기
    
    // 이미 같은 그래프에 속해있을 때 false 반환
    if(x == y) return false;
    
    if(x <= y) parent[y] = x;
    else parent[x] = y;
    return true;
}
Colored by Color Scripter
cs

union 함수는 매개변수로 받은 원소 x와 y를 같은 그래프로 합치는 함수이다. 이를 위해 먼저 x와 y의 부모를 찾는 과정을 거쳐야 한다. x와 y의 부모를 find 함수를 통해 찾은 뒤 만약 부모가 같다면 같은 그래프에 속해 있으므로 False를 반환한다.

부모가 다르다면 x, y 중 노드 번호가 작은 쪽이 부모가 되도록 한다.

매개변수로 전달해주는 값들의 비교가 확실하다면 !=로도 가능하다.

​

 

전체코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class Main {
    static int[] parent;
 
    // union 연산
    public static boolean union(int x, int y) {
        x = find(x);
        y = find(y);
        
        if(x == y) return false;
        
        if(x <= y) parent[y] = x;
        else parent[x] = y;
        return true;
    }
    
    // find 연산
    public static int find(int x) {
        if(parent[x] == x) return x;
        return find(parent[x]);
    }
    
     // parent 출력
    public static void parentPrint() {
        System.out.print("[ ");
        for (int i = 1; i < parent.length; i++) {
            System.out.print(parent[i]+ " ");
        }
        System.out.println("]");
    }
 
    public static void main(String[] args) {
        int n = 5;
        parent = new int[n + 1];
        // 부모 노드 초기화
        for (int i = 0; i < parent.length; i++) parent[i] = i;
        
        //위의 예제 실행
        union(1, 2);
        parentPrint();
        union(3, 4);
        parentPrint();
        union(3, 5);
        parentPrint();
        System.out.println("find(2): " + find(2));
        System.out.println("find(4): " + find(4));
        union(2, 4);
        parentPrint();
        System.out.println("find(4): " + find(4));
    }
}
Colored by Color Scripter
cs

 

 

 

 

 

 


참고)

https://velog.io/@suk13574/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98Java-%EC%9C%A0%EB%8B%88%EC%98%A8-%ED%8C%8C%EC%9D%B8%EB%93%9CUnion-Find-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98#-%EB%AA%A9%EC%B0%A8https://kistone.tistory.com/58

https://m.blog.naver.com/parkhj2416/221861837543

'Algorithm/응용' 카테고리의 다른 글
  • [이분탐색 - 응용] parametric search 개념 및 문제 풀이
s_y_130
s_y_130
  • s_y_130
    About SY
    s_y_130
  • 전체
    오늘
    어제
    • 분류 전체보기 (425) N
      • JAVA (54)
        • 더 자바 8 (0)
        • JAVA (41)
        • JAVA (JVM) (13)
      • Computer Science (86)
        • CS Basic (7)
        • OOP (11)
        • Design Pattern (16)
        • Network (8)
        • HTTP (6)
        • WEB (22)
        • OS (16)
      • DataBase (29)
        • DB theory (15)
        • MySQL (14)
        • Redis (0)
      • Collection Framework (1)
        • 구현 (1)
      • Data Structure (14)
        • Linear (9)
        • Non-Linear (5)
      • Algorithm (19)
        • Basic (12)
        • 응용 (2)
        • 완전 탐색(Brute Force) (1)
        • 다익스트라 (1)
        • Algorithm Problem (3)
      • Spring (100)
        • 스프링 핵심 원리 - 기본편 (9)
        • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (7)
        • 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술 (11)
        • 스프링 DB 1편 - 데이터 접근 핵심 원리 (6)
        • 스프링 DB 2편 - 데이터 접근 활용 기술 (10)
        • 스프링 핵심 원리 - 고급편 (13)
        • 스프링 부트 - 핵심 원리와 활용 (9)
        • Spring Cloud로 개발하는 MSA (1)
        • 재고시스템으로 알아보는 동시성이슈 해결방법 (4)
        • 개념 (27)
        • 테스트 (0)
        • Annotation (1)
        • Error Log (2)
      • TEST (0)
        • 부하 테스트 (0)
        • Practical Testing: 실용적인 테스트.. (0)
      • JPA (40)
        • 자바 ORM 표준 JPA 프로그래밍 (12)
        • 1편- 실전! 스프링 부트와 JPA 활용 (7)
        • 2편- 실전! 스프링 부트와 JPA 활용 (4)
        • 실전! 스프링 데이터 JPA (6)
        • 실전! Querydsl (6)
        • 개념 (5)
      • 백엔드 부트캠프[사전캠프] (33) N
        • TIL (12)
        • 문제풀이 (21) N
      • Open Source (0)
      • Book Study (1)
        • Morden Java in Action (1)
        • Real MySQL 8.0 Vol.1 (0)
        • TDD : By Example (0)
      • AWS (0)
        • EC2 (0)
      • git (2)
      • AI (22)
        • Machine Learning (17)
        • Deep Learning (0)
        • TensorFlow (1)
        • PyTorch (1)
        • YOLO (1)
        • Data Analysis (0)
        • Ai code Error (1)
        • Numpy (1)
      • MY (0)
      • WEB (15)
        • Django (3)
        • WEB 개념 (1)
        • React (1)
        • Maven (10)
      • Python (6)
      • 기초수학 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
s_y_130
[그래프/트리 - 응용] Union-Find / 서로소 집합
상단으로

티스토리툴바