- 배열에 각 node의 parent node를 저장한다.
- 재귀적으로 최상위 parent node를 탐색하고 이를 바탕으로 집합을 구분한다.
class UnionFind {
public boolean hasSameParent(int[] parentNodes, int a, int b) {
return findParent(parentNodes, a) == findParent(parentNodes, b);
}
public void union(int[] parentNodes, int a, int b) {
int parentA = findParent(parentNodes, a);
int parentB = findParent(parentNodes, b);
if (parentA > parentB) parentNodes[parentA] = parentB;
else parentNodes[parentB] = parentA;
}
private int findParent(int[] parentNodes, int node) {
if (parentNodes[node] == node) return node;
return findParent(parentNodes, parentNodes[node]);
}
}
O(eloge)
의 시간복잡도를 가진다.알고리즘의 흐름은 아래와 같다.
- edge들을 cost의 오름차순으로 정렬한다.
- 정렬된 edge 순서대로 cycle을 형성하지 않는 edge를 선택하여 MST에 추가한다.
- 모든 node가 같은 node를 parent로 가지면 MST가 완성된 것이므로 알고리즘을 종료한다.
public int kruskal(int n, int[][] costs) {
Arrays.sort(costs, (Comparator.comparingInt(o -> o[COST])));
int[] parentNodes = createCycleTable(n);
int answer = 0;
for (int[] edge : costs) {
if (!hasSameParent(parentNodes, edge[0], edge[1])) {
union(parentNodes, edge[0], edge[1]);
answer += edge[COST];
}
if (pathCreated(parentNodes)) break;
}
return answer;
}