[알고리즘] Kruskal's Algorithm
크루스칼 알고리즘은 최소 신장 트리(Minimum Spanning Tree, MST)를 구하는 대표적인 그리디 알고리즘입니다.
[알고리즘] Kruskal's Algorithm
개념
크루스칼 알고리즘은 최소 신장 트리(Minimum Spanning Tree, MST)를 구하는 대표적인 그리디 알고리즘입니다.
최소 신장 트리란?
- 그래프의 모든 정점을 연결하는 부분 그래프
- 사이클이 없음 (트리 구조)
- 간선의 가중치 합이 최소
더 자세한 내용은 아래 블로그에서도 보실 수 있습니다. https://wisdom-and-record.tistory.com/124
알고리즘 동작 원리
- 모든 간선을 가중치 기준으로 오름차순 정렬
- 가중치가 작은 간선부터 하나씩 선택
- 사이클을 형성하지 않는 간선만 MST에 추가
- 정점 수 - 1개의 간선이 선택될 때까지 반복
시간복잡도
- O(E log E): 간선 정렬에 필요한 시간
- Union-Find 연산: 거의 O(1) (아커만 함수의 역함수)
- 전체: O(E log E)
공간복잡도
- O(V): Union-Find 자료구조
- O(E): 간선 저장
특징 및 장단점
장점
- 구현이 비교적 간단
- 희소 그래프(간선이 적은 그래프)에서 효율적
- 그리디 알고리즘의 정확성이 증명됨
단점
- 밀집 그래프에서는 프림 알고리즘이 더 효율적일 수 있음
- 모든 간선을 정렬해야 함
관련 문제
프로그래머스 “섬 연결하기” 문제
https://school.programmers.co.kr/learn/courses/30/lessons/42861
소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct DisjointSet
{
vector<int> parent;
DisjointSet(int n): parent(n)
{
for(int i = 0; i < n; ++i) parent[i] = i;
}
int find(int x)
{
if(parent[x] == x) return x;
return parent[x] = find(parent[x]);
}
bool unite(int a, int b)
{
a = find(a);
b = find(b);
if(a == b) return false;
parent[b] = a;
return true;
}
};
int solution(int n, vector<vector<int>> costs)
{
int answer = 0;
sort(costs.begin(), costs.end(), [](auto& a, auto& b){ return a[2] < b[2]; });
DisjointSet dsu(n);
for(auto& edge: costs)
{
int u = edge[0];
int v = edge[1];
int w = edge[2];
if(dsu.unite(u, v))
{
answer += w;
}
}
return answer;
}
This post is licensed under CC BY 4.0 by the author.
