Home 백준 1717번 집합의 표현
Post
Cancel

백준 1717번 집합의 표현

정보

문제 바로가기 [클릭]

난이도: Gold4

관련 개념: #분리 집합 #자료구조


조건

시간 제한메모리 제한
1초128 MB

문제

초기에 {0}, {1}, {2}, … {n} 이 각각 n+1개의 집합을 이루고 있다. 여기에 합집합 연산과, 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산을 수행하려고 한다.

집합을 표현하는 프로그램을 작성하시오.


입력

첫째 줄에 n(1 ≤ n ≤ 1,000,000), m(1 ≤ m ≤ 100,000)이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는 a가 포함되어 있는 집합과, b가 포함되어 있는 집합을 합친다는 의미이다. 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산은 1 a b의 형태로 입력이 주어진다. 이는 a와 b가 같은 집합에 포함되어 있는지를 확인하는 연산이다. a와 b는 n 이하의 자연수 또는 0이며 같을 수도 있다.


출력

1로 시작하는 입력에 대해서 한 줄에 하나씩 YES/NO로 결과를 출력한다. (yes/no 를 출력해도 된다)


예제 입출력 1

입력

1
2
3
4
5
6
7
8
9
7 8
0 1 3
1 1 7
0 7 6
1 7 1
0 3 7
0 4 2
0 1 1
1 1 1

출력

1
2
3
NO
NO
YES

코드(파이썬)

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
import sys


sys.setrecursionlimit(10**6)

def find(num):
    if sets[num] != num:
        sets[num] = find(sets[num])
    return sets[num]

def union(num1, num2):
    set1 = find(num1)
    set2 = find(num2)
    
    if set1 != set2:
        if set1 < set2:
            sets[set2] = set1
        else:
            sets[set1] = set2
            
n, m = map(int, sys.stdin.readline().split())
sets = list(range(n+1))

for _ in range(m):
    op, num1, num2 = map(int, sys.stdin.readline().split())
    if op:
        print("YES" if find(num1) == find(num2) else "NO")
    else:
        union(num1, num2)


특이사항

  • 해결방식
    • 기존의 리스트 이용 집합 표현 방식 사용
    • find 함수에서 시간이 다수 소요
    • 각 집합이 가리키는 노드를 하나로 갱신하는 방법을 이용해 시간 단축

참고문헌

  • 문병로, 쉽게 배우는 알고리즘 :관계 중심의 사고법, 문병로, 2018
This post is licensed under CC BY 4.0 by the author.

백준 1068번 트리

백준 2156번 포도주시식

Comments powered by Disqus.