CS/Algorithm
서로소 집합(Disjoint Set) & 유니온 파인드(Union Find) (with. Java)
J.BF
2023. 8. 27. 18:18
서로소 집합(Disjoint Set) 이란?
서로소 집합은 서로 공통 원소가 없는 둘 이상의 집합들을 의미한다.
고등학교 때 반 별로 나눠 운동회를 진행했던 것을 생각하면 이해가 쉬울 것같다.
보통 가장 효율적인 트리 구조를 이용해서 구현한다.
유니온 파인드란(Union Find) 이란?
유니온 파인드는 서로소 집합을 만들 때 사용하는 알고리즘이다.
각 집합에는 대표 번호를 가지며 2가지 연산을 통해 두 집합을 합치거나 해당 집합의 대표 번호를 찾을 수 있다.
- union(a, b): a와 b의 집합을 합친다.
- findSet(a): 대표번호(트리에서는 최상위 부모)를 찾아 반환한다.💡findSet의 경로 압축
findSet
구현 시 경로 압축을 사용하여 속도를 더 빠르게 할 수 있다경로 압축을 사용하지 않은경우, 트리 구조가 한 쪽으로 치우쳐 LinkedList같은 모양이 나온다면 O(N)이 된다.
하지만 경로 압축을 사용하는 경우, 대표번호를 찾기 위해 거쳐간 관련 경로의 대표번호 정보를 최종 대표번호 업데이트하여 깊이를 줄일 수 있다. 시간 복잡도는 평균적으로 O(α(N))이다.
- α(N): 아커만 함수의 역함수. N이 얼마나 커지든지 매우 작은 상수 값을 가짐. (아주 큰 N값에도 빠르게 동작 가능)
구현 (Java)
int[] parents; // i번째 멤버의 부모 정보들
// 자기자신을 부모로 세팅 (멤버 번호는 0부터 시작해서 N-1로 끝남)
void makeSet(int n) {
for (int i = 0; i < n; i++) {
parents[i] = i;
}
}
// a멤버에 대한 부모 찾기
int findSet(int a) {
if (a == parents[a]) { // 자기자신이 최상위 부모라면 종료
return a;
}
// 상위 부모 탐색 재귀로 탐색
return parents[a] = findSet(parents[a]); // 경로압축 O: O(α(N))
// return findSet(a); // 경로압축 X: O(N)
}
// a의 집합과 b의 집합을 같은 집합으로 묶기
void union(int a, int b) {
a = findSet(a);
b = findSet(b);
if (a != b) {
parents[b] = a; // 부모가 다르면 a를 부모로 묶기 (사용에 따라 다른 방식으로 표현해도 됨)
}
}
💡
백준 관련 문제
Uploaded by N2T