최소 신장 트리(Mininum Spanning Tree)
Updated:
최소 신장 트리?
평소처럼 알고리즘 문제를 하나 풀어보려고 읽어보니,
그래프
를 사용하는 문제였다.
기존에 내가 알고있던 그래프 알고리즘은
다익스트라
알고리즘과 플로이드-워셜
알고리즘이었는데,
문제를 아무리 쳐다보고 있어도 위 알고리즘들과는 거리가 멀어보였다.
그리하여 힌트를 얻고자 분류를 살짝 열어보니 최소 신장 트리
라는
처음보는 알고리즘으로 분류되어 있었다.
이럴 땐 이론을 검색해보고 구현은 직접하자! 라는 생각을 갖고있기 때문에
구글을 통해 대략적인 개념을 살펴보았다.
내가 해결하고자 하는 문제가 최소 신장 트리
의 이론을 그대로 옮겨서 문제로 표현한 것이었다.
노드의 갯수와 각 노드들을 연결하는 간선들의 종류 및 비용이 주어졌을 때,
최소비용으로 모든 노드를 공유시키는 것
으로 정리할 수 있을 것 같다.
그 중에서도 프림
알고리즘과 크루스칼
알고리즘 두가지 방법을 봤는데,
나는 크루스칼
알고리즘을 사용하는 쪽이 더 좋을 것 같았다.
크루스칼 알고리즘
전체적인 과정은 이러했다. (노드
: N
개, 간선
: M
개)
- 모든 간선을 비용을 기준으로 오름차순으로 정렬한다.
- 모든 간선을 비용이 낮은 순으로 반복하여 다음의 검사를 시행한다.
- 간선의 양 끝이 가리키는 노드가 서로 이미 공유 중인가 판단한다. (사이클을 만들지 않는다.)
- 공유 중이라면 무시한채 다음 간선으로 넘어가고, 공유 중이지 않다면 해당 간선을 확정한다. (이 문제에서는 출력값에 더해줬다.)
N
개의 노드를 서로 공유하기 위해서는N-1
개의 간선만 있으면 되기 때문에,N-1
개의 간선이 확정된 순간 반복문을 종료한다. 기존에 간선의 비용에 맞추어 오름차순으로 정렬했기 때문에, 간선이 모두 확정된 순간이 최소비용이다.
문제에서의 활용
크루스칼 알고리즘을 정말 똑같이 구현하기만 하면 문제를 해결할 수 있었다.
간선의 양 끝의 노드가 이미 공유 중인지 판단하기 위해 Union-find
자료구조를 사용했다.
다른 문제를 해결하면서 한번 배워둔 적이 있는데, 어렵지 않아서 바로 활용할 수 있었다!!
Leave a comment