Algorithm/Study

[Algorithm] 유니온 파인드(Union-Find) 개념, 코드(C++)

BeNI 2021. 5. 20. 02:58
728x90

1. 유니온 파인드

1) 의미

- 그래프 알고리즘으로 Union(합집합) + Find(찾다)로 '합집합 찾기' 라는 의미를 가지고 있다.

- 서로소 집합(Disjoint Set) 이라고 불리기도 한다.

- 여러 노드 중 두 노드를 선택하여 같은 그래프에 속해 있는 지 확인하는 알고리즘이다. 

 

2) 연산

- 2가지 연산이 존재한다.

① Find(x) : 원소 𝑥가 속한 부분집합을 찾는다. 보통 𝑥가 속한 부분집합의 대표 원소를 되돌려준다

② Union(x, y) : 원소 𝑥가 속한 부분집합과 원소 𝑦가 속한 부 분집합의 합집합을 구한다.

* 각 부분집합은 트리로 나타낸다.

 

3) 구현(배열 이용)

- 미리 해야할 과정 

  • 노드의 개수 만큼 배열을 선언한다.
  • 각 노드의 루트노드를 가르키는 배열을 선언하고, 초기화 한다. (parent배열)
  • 주어진 조건에 맞게 각 노드의 parent 배열의 값은 그 노드가 가르키는 노드로 바꿔준다.

 

ⓐ Find : 루트 노드를 찾는 함수이므로 루트에 도달할 때까지 계속 부모노드를 찾아 올라간다.

int find(int x) {
	if (parent[x] == x) return x;
	return parent[x] = find(parent[x]);
}

ⓑ Union : 𝑥를 (혹은 𝑦를) 포함하는 부분집합을 나타내는 트리를 다른 것의 부트리로 만들면 된다.

void merge(int x, int y) {
	x = find(x);
	y = find(y);
	if (x == y) return;
	parent[y] = x;
}

- x, y가 매개변수로 들어왔을 때, x와 y의 루트노드가 같다면 같은 집합이므로 종료하고,

아니라면 y의 부모를 x로 바꿔준다.

 

 

ⓒ 시간복잡도 

- 일반적으로 유니온파인드를 사용하면, 평균적으로 트리의 높이만큼 탐색하게되므로 시간복잡도는 O(logn)이된다.

- 최악의 경우로 경사트리일때는 트리의 높이가 n이므로 시간복잡도는 O(N)이다.

따라서 시간복잡도는 O(logn)~O(N) 이다.

 

2. 유니온 파인드의 가중법칙

- union(𝑥,𝑦) 연산에서 원소 𝑥와 𝑦가 속한 부분집합에 대한 트리를 각각 𝑇𝑥, 𝑇𝑦라고 할 때,

  𝑇𝑥의 노드 개수가 더 많으면 𝑇𝑦의 루트를 𝑇𝑥의 루트의 자식이,

  그렇지 않으면 𝑇𝑥의 루트를 𝑇𝑦의 루트의 자식이 되도록 만든다.

>>> 가중 법칙에 따라 구성된 트리의 높이는, 노드 개수를 𝑛이라고 할 때, log2 𝑛 을 넘지 않는다.

 

- 증명 : (수학적 귀납법으로 증명한다)

  • 𝑛 = 1인 기본 경우는 ℎ = 0 = log2 𝑛 이므로 성립한다.
  • 𝑛 ≥2라고 둔다. 𝑇𝑖의 노드 개수를 𝑛𝑖 , 높이를 ℎ𝑖라고 두고, 𝑛1 ≥ 𝑛2이라고 가정한다.
  • 그러면 ℎ = max ℎ1, ℎ2 + 1 이다.
  • ℎ1 ≤ log2 𝑛1 ≤ log2 𝑛 이고,
  • ℎ2 ≤ log2 𝑛2 ≤ log2 𝑛 2 ≤ log2 𝑛 − 1이다.
  • 따라서 ℎ ≤ log2 𝑛 이 성립한다.

 

 

+ 유니온 파인드 백준문제 : 1717번: 집합의 표현 (acmicpc.net)

 

1717번: 집합의 표현

첫째 줄에 n(1 ≤ n ≤ 1,000,000), m(1 ≤ m ≤ 100,000)이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는

www.acmicpc.net

개념 이해하고 풀어보면 좋을 듯!

728x90