크래프톤 정글 주제별 탐구 -크루스칼 알고리즘-
정의
크루스칼 알고리즘이란, MST를 구하기 위해 사용되는 알고리즘이다.
동작 방식
간단히 크루스칼 알고리즘의 동작 순서에 대해 작성해보자.
- 주어진 모든 간선 정보에 대해 간선 비용이 낮은 순서(오름차순)로 정렬을 수행
- 정렬된 간선 정보를 하나씩 확인 하면서 현재의 간선이 노드들 간의 사이클을 발생시키는지 확인
- 만약 사이클이 발생하지 않은 경우, 최소 신장 트리에 포함시키고 사이클이 발생한 경우, 최소 신장 트리에 포함시키지 않음
- 1번~3번 과정을 모든 간선 정보에 대해 반복 수행
이때 2번의 과정에서 사이클 발생 여부 의 코드를 짜기가 어려운데, 이는 노드들의 부모 노드가 같다면 사이클이 발생했다고 보고, 그렇지 않다면 사이클이 발생하지 않았다고 보는 방식을 통해 확인한다.
이 부모 노드가 같다 라는 부분은 Union 이라는 과정을 통해 구할 수 있는데, 크루스칼 알고리즘에서 이 과정은 다음과 같다.
- 먼저, A와 B의 parent값을 비교하고, 둘이 다를 때 진행한다.
- A의 parent, parent의 parent, … 들 중 x == parent(x) 인 값을 찾는다.
- B 역시 마찬가지로 y == parent(y)를 찾는다.
- 이 x, y를 비교하여, 둘 중 작은 값으로 둘 다 통일시킨다.
- 이를 통해 부모 값을 찾는다!
또한, 이 때 선택되는 간선의 총 수는 노드 수 -1(V-1)이 될 것이다.
구현
문제 1197번
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
import sys
def get_Parent(val):
if parent_list[val] == val:
return val
parent_list[val] = get_Parent(parent_list[val])
return parent_list[val]
def union_parent(a, b):
a = get_Parent(a)
b = get_Parent(b)
if a < b:
parent_list[b] = a
else:
parent_list[a] = b
V, E = map(int, sys.stdin.readline().rstrip().split())
weight_list = []
parent_list = []
for i in range(V):
parent_list.append(i)
for i in range(E):
_from, _to, _weight = map(int, sys.stdin.readline().rstrip().split())
_from -= 1
_to -= 1
weight_list.append([_weight, _from, _to])
weight_list.sort()
_sum = 0
for weight in weight_list:
if get_Parent(weight[1]) != get_Parent(weight[2]):
union_parent(weight[1], weight[2])
_sum += weight[0]
print(_sum)
This post is licensed under CC BY 4.0 by the author.