728x90
시간 제한 2초, 메모리 제한 128MB
# 조건
- 초기에 $n+1$개의 집합 ${0}, {1}, {2}, \dots , {n}$이 있다.
- 여기에 합집합 연산과, 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산을 수행하려고 한다.
- 집합을 표현하는 프로그램을 작성하시오.
입력
- 첫째 줄에 $n$, $m$이 주어진다.
- $m$은 입력으로 주어지는 연산의 개수이다.
- 다음 $m$개의 줄에는 각각의 연산이 주어진다. 합집합은 $0$ $a$ $b$의 형태로 입력이 주어진다.
- 이는 $a$가 포함되어 있는 집합과, $b$가 포함되어 있는 집합을 합친다는 의미이다.
- 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산은 $1$ $a$ $b$의 형태로 입력이 주어진다.
- 이는 $a$와 $b$가 같은 집합에 포함되어 있는지를 확인하는 연산이다.
출력
- 이는 $a$와 $b$가 같은 집합에 포함되어 있는지를 확인하는 연산이다.
- 1로 시작하는 입력에 대해서 a와 b가 같은 집합에 포함되어 있으면 "Yes", 또는 "yes", 그렇지 않다면 "No" 또는 "no"를 한 줄에 하나씩 출력한다.
제한
- 1<=n<=1,000,000
- 1<=m<=100,000
- 0<=a, b<=n
- a, b는 정수
- a와 b는 같을 수도 있다.
# 접근 방법
- 단순히 집합을 합쳐서 모든 입력에 대해 확인한다면 시간 초과가 발생할 것이다.
- 따라서, union find를 이용하여 풀어준다.
- 속한 집합을 나타낼 parents 리스트를 [i for i in range(N)]으로 만들어준다.
- 0번 명령어가 들어왔다면
- a와 b를 union 시켜주는데 작은 번호를 기준으로 해준다.
- 1번 명령어가 들어왔다면 각각의 find 값이 같다면 Yes, 아니라면 No를 출력해준다.
- 여기서 parent 값을 바로 확인하지 않는 이유는
- 1 2, 3 4 의 집합을 합친 후 2 3 을 합친다면
- 4번의 집합 3번으로 기록되어 있기 때문이다.
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
def find(x):
if parents[x] != x:
x = find(parents[x])
return x
def union(x, y):
x = find(x)
y = find(y)
if x > y:
parents[x] = y
else:
parents[y] = x
N, M = map(int, input().split())
parents = [i for i in range(N+1)]
for _ in range(M):
q, a, b = map(int, input().split())
if q == 0:
union(a, b)
else:
print('YES' if parents[a] == parents[b] or find(a) == find(b) else 'NO')
728x90
'ALGORITHM > 자료구조' 카테고리의 다른 글
[백준 5446번] 파이썬 - 용량 부족 (1) | 2023.08.27 |
---|---|
[백준 19583번] 파이썬 - 싸이버 개강총회 (0) | 2023.08.26 |
[백준 17413번] 파이썬 - 단어 뒤집기 2 (0) | 2023.08.26 |
[백준 19585번] 파이썬 - 전설 (0) | 2023.08.16 |
[백준 28099번] 파이썬 - 이상한 배열 (0) | 2023.08.15 |