여러개의 노드가 존재할 때, 두 노드를 선택해 같은 그래프의 노드인지 확인하고 합치는 알고리즘
두 트리를 합치는 과정
위 그림과 같이 루트가 4와1인 두 그래프가 있을 때, 한 그래프로 합치는 과정
⇒ 한 그래프의 루트노드를 다른 그래프의 자식으로 넣어줌
9와 6는 같은 그래프인가? → 놉
why? 루트가 다르기 때문
그런데.. 그래프의 깊이가 깊어질수록 부모를 찾는데 오래 걸리네..?
나는 이 작업을 여러번 해야하는데 너무 비효율 적인 것 아냐..?
⇒ 루트를 찾고, 루트의 자식이 되자!
오호! 다음 번에 6를 조사할땐 빠르게 루트를 찾을 수 있겠다!
경로 압축을 하지 않을 경우 최악의 경우 O(N)의 복잡도를 가짐
{1} ← {2} ← {3} … ← {n}
크게 배열과 트리 방법이 있는데, 배열이 간단해서 보통 배열을 활용함
int find(int n){
if(p[n] == n) return n;
return p[n] = find(p[n]); //경로압축
}
void uni(int a, int b){
A = find(a);//A의 root를 찾음
B = find(b);//B의 root를 찾음
if(A==B) return;//A와 B가 같으면 같은 그래프이므로
if(A < B) p[B] = A;
else p[A] = B;
}
최적화 여부, 순서 등 매번 달라져 구하기 까다로움.
경로 압축을 하지 않을 경우 최악의 경우 O(N)이며, 트리가 넓게 분포되있으면 O(logN)정도이지 않을까..?
실제 평균 시간복잡도는 O(α(N))O(α(N))이라고 한다.
α(N)은 애커만(Ackermann) 역함수로 매우 빠르게 증가하는 애커만 함수로부터 정의된다.
- 1≤N<3인 경우 α(N)=1
- 3≤N<7인 경우 α(N)=2
- 7≤N<63인 경우 α(N)=3
- 63≤N< 인 경우 α(N)=4
https://www.acmicpc.net/problem/1717 기본 문제
https://www.acmicpc.net/problem/1976 기본 문제
https://www.acmicpc.net/problem/10775 응용 문제
https://www.acmicpc.net/problem/3780 TLE 고려하여 풀기
참고