728x90
반응형
https://www.acmicpc.net/problem/1717
1717번: 집합의 표현
첫째 줄에 n(1 ≤ n ≤ 1,000,000), m(1 ≤ m ≤ 100,000)이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는
www.acmicpc.net
문제 자체가 이해가 어렵지는 않은 문제다.
이 문제를 풀기 위해서는 유니온 파인드가 뭔지 알아야 한다.
그래프 풀이법의 일종으로 볼 수 있다.
노드들을 합치고(union), 부모를 찾아준다(find)
일련의 과정은 다음과 같다.
1. 원소 두 개를 입력받고 Union 함수를 호출한다.
2. 입력받은 원소의 부모를 find 함수를 이용해서 '재귀적으로' 찾아 준다.
3. 부모는 배열에서의 인덱스의 값과 본인이 가지고 있는 값이 같을 것이다. 해당 조건을 만족하면 return, 왜 이런 조건을 만족해야 하냐면 배열을 처음 만들 때 0번째에 0, 1번째에 1, 2번째에 2... 이런 식으로 만들었다. 부모의 노드는 쉽게 생각하면 기준을 의미하기도 한다.
기준이 초기값과 바뀐다면 우리는 그걸 기준이라고 부를 수 없다.
4. 입력받은 원소 두 개의 부모 노드를 반환받았으면 둘 중 더 큰 좌표의 값을 작은 원소로 바꿔 준다. 반대가 돼도 상관없다.
5. 부모가 같은지 찾는 것은 find 함수를 통해서 찾으면 된다.
import sys
sys.setrecursionlimit(100000)
n,m = map(int,sys.stdin.readline().split())
arr = []
for i in range(n+1):
arr.append(i)
def find(a):
if a == arr[a]:
return a
arr[a] = find(arr[a])
return arr[a]
def union(a,b):
a = find(a)
b = find(b)
arr[max(a,b)] = min(a,b)
for i in range(m):
ord,a,b = map(int,sys.stdin.readline().split())
if ord == 0:
union(a,b)
else:
if find(a) == find(b):
print('YES')
else:
print('NO')
재귀의 개념이 잘 잡혀 있다면 이해가 수월하다.
역시 재귀가 들어가면 재밌다.
728x90
반응형
'Algorithm & Data Structure' 카테고리의 다른 글
백준 - 1043번(그래프) (0) | 2022.08.18 |
---|---|
백준 - 1976번(유니온 파인드, 재귀) (0) | 2022.08.17 |
백준 - 14002번(DP, LIS) (0) | 2022.08.15 |
백준 - 11045번(DP,LIS 응용) (0) | 2022.08.15 |
백준 - 9663번(백트래킹, N-Queen) (0) | 2022.08.15 |