-
크루스칼 알고리즘Algorithms in Python/notes 2021. 2. 7. 08:35
크루스칼(Kruskal) 알고리즘
Spanning Tree
하나의 그래프가 있을 때 모든 노드를 포함하면서 사이클이 존재하지 않는 부분 그래프
MST (Minimum Spanning Tree) 최소 스패닝 트리
가중치 그래프의 스패닝 트리들 중에서 에지들의 가중치의 합이 최소인 스패닝 트리
'임의의 두 집에 대하여 가로등이 켜진 도로만으로도 오갈 수 있도록'
'임의의 두 집 사이에 경로가 항상 존재하면서 길의 유지비의 합을 최소로'
크루스칼 알고리즘
1. 간선 데이터를 비용에 따라 오름차순으로 정렬한다.
2. 간선을 하나씩 확인하며 현재의 간선이 사이클을 발생시키는지 확인한다.
- 사이클이 발생하지 않는 경우 최소 스패닝 트리에 포함시킨다.
- 사이클이 발생하는 경우 최소 스패닝 트리에 포함시키지 않는다.
3. 모든 간선에 대하여 2번의 과정을 반복한다.
대표적인 최소 스패닝 트리 알고리즘으로 가장 적은 비용으로 모든 노드를 연결할 수 있다.
가장 비용이 작은 것부터 포함시키기 때문에 그리디 알고리즘으로 분류된다.
• Kruskal 알고리즘 소스코드
# 특정 원소가 속한 집합을 찾기 def find_parent(parent, x): # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 if parent[x] != x: parent[x] = find_parent(parent, parent[x]) return parent[x] # 두 원소가 속한 집합을 합치기 def union_parent(parent, a, b): a = find_parent(parent, a) b = find_parent(parent, b) if a < b: parent[b] = a else: parent[a] = b # 노드의 개수와 간선(union 연산)의 개수 입력받기 v, e = map(int, input().split()) parent = [0] * (v + 1) # 부모테이블 초기화 # 모든 간선을 담을 리스트와 최종 비용을 담을 변수 edges = [] result = 0 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, v + 1): parent[i] = i # 모든 간선에 대한 정보를 입력받기 for _ in range(e): a, b, cost = map(int, input().split()) # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 edges.append((cost, a, b)) # 간선을 비용순으로 정렬 edges.sort() # 간선을 하나씩 확익하며 for edge in edges: cost, a, b = edge # 사이클이 발생하지 않는 경우에만 집합에 포함 if find_parent(parent, a) != find_parent(parent, b): union_parent(parent, a, b) result += cost print(result)
• Kruskal 알고리즘의 시간 복잡도
간선의 개수가 E개일 때, E개 정렬 O(ElogE)
* 이것이 코딩테스트다 with 파이썬 - 나동빈
'Algorithms in Python > notes' 카테고리의 다른 글
다익스트라 최단 경로 알고리즘 (0) 2021.02.10 위상 정렬 (0) 2021.02.07 Union-Find 알고리즘 (0) 2021.02.07 DFS / BFS (0) 2021.01.29 이진 탐색, bisect 라이브러리 (0) 2021.01.21