[백준] Gold V. 집합의 표현

2024. 7. 30. 12:35·Algorithm/백준

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

 

알고리즘 유형
  • 그래프
  • 유니온 파인드

 

풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class boj1717 {
    static int n, m;
    static int [] parent;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());

        parent = new int[n + 1];
        for(int i = 1; i <= n; i++){
            parent[i] = i; // i값으로 초기화
        }

        for(int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int check = Integer.parseInt(st.nextToken());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            if (check == 0) {
                union(a,b);
            }

            else if (check == 1) {
                check(a,b);
            }
        }

    }

    public static void check(int a, int b) {
        a = find(a);
        b = find(b);
        if (a == b) {
            System.out.println("YES");
        }
        else {
            System.out.println("NO");
        }
    }

    public static void union(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) {
            parent[b] = a;
        }
    }

    public static int find(int n) {
        if (parent[n] == n) { // 배열 인덱스와 값이 같다면 해당 값 리턴
            return n;
        }
        // System.out.println("find: " + find(parent[n]));
        int m = find(parent[n]);
        parent[n] = m;
        return m;
    }
}

 

 

회고

 

크루스칼 알고리즘과 프림 알고리즘을 풀기 전에, 유니온 파인드 알고리즘에 대한 이해가 선행되어야 했기 때문에 찾아서 공부했다. 

 

유니온 파인드는 언제 사용될까?

서로 다른 2개의 원소가 같은 집합인지 여부를 체크할 때 사용된다. 유니온 파인드에는 union 메서드와 find 메서드가 존재하는데, 이 두개를 이해하는게 중요하다.

 

처음에 입력을 받을 때 1차원 배열에 각 노드의 번호를 값으로 입력 받는다.

 

int [] parent

1 2 3 4 5 6
1 2 3 4 5 6

find

특정 노드 n에 대해서 대표 노드를 리턴하는 함수

    public static int find(int n) {
        if (parent[n] == n) { // 배열 인덱스와 값이 같다면 해당 값 리턴
            return n;
        }
        // System.out.println("find: " + find(parent[n]));
        int m = find(parent[n]);
        parent[n] = m;
        return m;
    }

 

배열의 인덱스와 값이 같다면 바로 리턴해주면 된다. ex) parent[1] = 1

 

 

하지만, 노드가 이렇게 연결되어 있다면,

1 2 3
1 1 2

 

이런식으로 배열이 표현될 것이다. (A,B,C가 1,2,3이라고 가정)

 

여기서 1과 3의 연결 여부는 어떻게 알 수 있을까? 

 

재귀적으로 3의 대표 노드인 2를 리턴하고, 또 2는 대표 노드인 1을 리턴해서 최종적으로 1과 3이 연결되어 있음을 확인할 수 있다.

 

union

각 노드가 속한 집합을 하나로 합치는 함수

 

public static void union(int a, int b) {
    a = find(a);
    b = find(b);
    if (a != b) {
        parent[b] = a;
    }
}

 

앞서 선언한 find 함수를 통해서 값을 가져오고, 두 개의 값이 다르다면 대표 노드를 바꿔준다.

 

일반적으로, 더 작은 쪽이 대표 노드가 된다. 

'Algorithm > 백준' 카테고리의 다른 글

[백준] Gold IV. 케이크 자르기  (0) 2024.09.05
[백준] Gold IV. 여행 가자  (0) 2024.08.02
[그래프] 위상정렬  (1) 2024.07.29
[백준] Silver I. 절댓값 힙  (2) 2024.07.23
[백준] Silver II. 생태학  (0) 2024.07.22
'Algorithm/백준' 카테고리의 다른 글
  • [백준] Gold IV. 케이크 자르기
  • [백준] Gold IV. 여행 가자
  • [그래프] 위상정렬
  • [백준] Silver I. 절댓값 힙
미네구스
미네구스
  • 미네구스
    망구스 blog
    미네구스
  • 전체
    오늘
    어제
    • 분류 전체보기 (174)
      • Kotlin (0)
      • 시큐리티 (0)
        • 개발자 유미 (0)
      • 배포 (4)
      • 회고 (0)
      • Algorithm (143)
        • 프로그래머스 코딩테스트 문제풀이전략 (37)
        • 백준 (66)
        • 프로그래머스 (18)
        • Leetcode (22)
        • 코테 팁 (0)
      • 프로젝트 (8)
        • WEPIK (3)
        • PICK-O (5)
      • CS (1)
        • 운영체제 (5)
        • 네트워크 (1)
        • 면접스터디 (2)
      • 면접 (0)
        • 코테후기 (0)
        • 면접후기 (0)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    백트래킹
    N과 M
    `
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
미네구스
[백준] Gold V. 집합의 표현
상단으로

티스토리툴바