[BOJ 1197] 최소 스패닝 트리
- 문제풀이
문제
그래프가 주어졌을 때, 그 그래프의 최소 스패닝 트리를 구하는 프로그램을 작성하시오.
최소 스패닝 트리는, 주어진 그래프의 모든 정점들을 연결하는 부분 그래프 중에서 그 가중치의 합이 최소인 트리를 말한다.
입력
첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이 가중치 C인 간선으로 연결되어 있다는 의미이다. C는 음수일 수도 있으며, 절댓값이 1,000,000을 넘지 않는다.
그래프의 정점은 1번부터 V번까지 번호가 매겨져 있고, 임의의 두 정점 사이에 경로가 있다. 최소 스패닝 트리의 가중치가 -2,147,483,648보다 크거나 같고, 2,147,483,647보다 작거나 같은 데이터만 입력으로 주어진다.
출력
첫째 줄에 최소 스패닝 트리의 가중치를 출력한다.
제한
| 시간 제한 | 메모리 제한 |
|---|---|
| 1sec | 128MB |
풀이
그래프의 모든 정점을 연결하면서 간선 가중치의 합이 최소가 되는 부분 그래프인 최소 스패닝 트리를 구하는 가장 전형적인 문제이다.
이 문제를 해결하기 위해 크루스칼 알고리즘을 사용하였다. 알고리즘의 동작 과정은 다음과 같다.
- 간선 정렬: 주어진 모든 간선($E$)을 가중치($C$)를 기준으로 오름차순 정렬한다.
- 간선 선택: 가중치가 낮은 간선부터 차례대로 확인하며 트리 구조에 포함시킬지 결정한다.
- 사이클 검사: 선택한 간선이 트리에 추가되었을 때 사이클(Cycle)이 발생하는지 확인해야 한다. 이를 위해 분리 집합 자료구조를 활용한다.
- 간선의 양 끝점 $A$와 $B$의 루트 노드가 같다면 이미 연결된 상태이므로 무시한다.
- 루트 노드가 다르다면 사이클이 생기지 않으므로
merge연산을 통해 두 집합을 합치고 가중치를 합산한다.
- 종료 조건: 트리의 정의에 따라 간선의 개수가 $V-1$개가 되면 모든 정점이 연결된 것이므로 탐색을 종료한다.
입력 데이터의 정점 개수가 최대 $10\,000$개, 간선이 $100\,000$개이므로 간선을 정렬하는 데 $O(E \log E)$의 시간이 소요되며, 이는 시간 제한 내에 충분히 해결 가능하다.
소스코드
Github Link : Source Code
참고 알고리즘 : 최소 스패닝 트리