초기에 {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 를 출력해도 된다)
서로소 집합을 활용하는 문제. 서로소 집합 자료구조는 합집합(union) 연산과 찾기(find) 연산으로 구성된다.
찾기 연산은 특정한 원소의 부모 원소를 찾는 연산이다. 만약 어떤 두 원소가 같은 부모 원소를 갖는다면 두 원소는 같은 집합에 속한다는 것이다.
합집합 연산은 2개의 원소가 포함된 집합을 하나의 집합으로 합치는 연산으로, 찾기 연산을 이용하여 두 원소의 부모 원소 번호를 비교한 수 더 작은 부모 원소로 합쳐준다.
import sys
sys.setrecursionlimit(1000000) # 재귀 깊이 제한 늘리기
input = sys.stdin.readline
n, m = map(int, input().split())
parent = [i for i in range(n + 1)] # 자기 자신을 부모로 갖는 n + 1개 집합
# 찾기 연산(같은 집합에 속하는지 확인하기 위한 함수)
def find_parent(x):
if parent[x] != x:
parent[x] = find_parent(parent[x])
return parent[x]
# 합집합 연산(두 집합을 합치기 위한 함수)
def union_parent(a, b):
a = find_parent(a)
b = find_parent(b)
if a < b: # 값이 더 작은 쪽을 부모로
parent[b] = a
else:
parent[a] = b
for _ in range(m):
opr, a, b = map(int, input().split())
if opr == 0:
union_parent(a, b)
else:
if find_parent(a) == find_parent(b):
print("YES")
else:
print("NO")
코드가 메모리 초과 나오네요...