🛣️
고급 그래프
Kruskal(유니온 파인드)·Prim
단원 26 — 최소 신장 트리 (Minimum Spanning Tree)
모든 정점을 잇는 최소 비용 트리. 유니온 파인드 자료구조와 함께 학습합니다.
MSTKruskalPrimUnion-Find
소요 시간
⏱ 약 1.5시간
난이도
📊 고급
선수 조건
🎯 그래프·heap
결과물
모든 정점을 잇는 최소 비용 트리. 유니온 파인드 자료구조와 함께 학습합니다.
이 강의에서 배우는 것
- 1크루스칼(Kruskal) 알고리즘을 유니온-파인드(Union-Find)와 함께 구현할 수 있다.
- 2프림(Prim) 알고리즘을 heapq로 구현하여 밀집 그래프에서 활용할 수 있다.
- 3MST의 절단 성질(Cut Property), 사이클 성질(Cycle Property)을 설명하고 응용 문제에 적용할 수 있다.
개요
💡
**Part 07 고급 그래프** | 이전: [25_플로이드_워셜](../25_플로이드_워셜/) | 다음: [27_실전_패턴](../../08_응용/27_실전_패턴/)
소개
최소 신장 트리(MST)는 가중치 연결 무방향 그래프에서 **모든 정점을 연결하는 트리 중 간선 가중치 합이 최소**인 것입니다. 네트워크 설계, 클러스터링, 근사 알고리즘에 핵심적으로 사용됩니다.
- **트리 조건**: V개 정점, V-1개 간선, 사이클 없음
- **대표 알고리즘**: Kruskal (O(E log E)), Prim (O((V+E) log V))
핵심 개념
1. MST 성질
**절단 성질 (Cut Property)**: 그래프를 임의로 두 집합 S, V-S 로 나눌 때, 두 집합을 연결하는 가장 가벼운 간선은 반드시 MST에 포함됩니다.
**사이클 성질 (Cycle Property)**: 임의의 사이클에서 가장 무거운 간선은 MST에 포함되지 않습니다.
2. Kruskal 알고리즘
text
1. 모든 간선을 가중치 오름차순 정렬 O(E log E)
2. 각 정점을 독립적인 집합으로 초기화 O(V)
3. 정렬된 간선을 순서대로 처리:
- 두 끝점이 다른 집합이면:
→ 간선을 MST에 추가 (Union)
→ V-1개 간선이 추가되면 종료
- 같은 집합이면 사이클 형성 → 건너뜀
시간: O(E log E) + O(E α(V)) ≈ O(E log E)
공간: O(V + E)3. Prim 알고리즘
text
1. 임의의 출발 정점을 MST에 추가
2. MST에 인접한 미선택 간선 중 최소 가중치 간선 선택
3. 선택된 정점을 MST에 추가
4. V-1 개 간선이 추가될 때까지 반복
시간: O((V+E) log V) — heapq 구현
공간: O(V + E)4. Union-Find (서로소 집합) 구현
text
경로 압축 (Path Compression):
find(x): 루트를 찾으면서 x의 부모를 루트로 직접 연결
→ 이후 find 연산 O(1) 에 가까워짐
랭크에 의한 합치기 (Union by Rank):
union(x, y): 랭크(트리 높이 추정)가 낮은 트리를 높은 트리 아래로 합침
→ 트리 높이 O(log V) 보장
상각 복잡도: O(α(V)) ≈ O(1) (α는 역아커만 함수)5. 텍스트 아트: Kruskal 단계별 예시
text
그래프 (무방향):
1 ──4── 2 ──2── 4
│ / \ │
3 1 3 6
│ / \ │
3 ────5──── 5──7──6
간선 정렬:
(2,3): 1 (1,3): 3 (2,4): 2 (2,5): 3 (1,2): 4 (3,5): 5 (4,5): 6 (5,6): 7
단계:
┌─────┬───────┬─────────────────┬──────────────────┐
│ 순서 │ 간선 │ 같은 집합? │ MST 간선 │
├─────┼───────┼─────────────────┼──────────────────┤
│ 1 │ 2-3:1 │ 아니오 → 추가 │ {2-3} │
│ 2 │ 2-4:2 │ 아니오 → 추가 │ {2-3, 2-4} │
│ 3 │ 1-3:3 │ 아니오 → 추가 │ {2-3, 2-4, 1-3} │
│ 4 │ 2-5:3 │ 아니오 → 추가 │ {… , 2-5} │
│ 5 │ 1-2:4 │ 예 (사이클) → 스킵│ 변화없음 │
│ 6 │ 3-5:5 │ 예 (사이클) → 스킵│ 변화없음 │
│ 7 │ 5-6:7 │ 아니오 → 추가 │ {… , 5-6} V-1=5개│
└─────┴───────┴─────────────────┴──────────────────┘
MST 총 가중치: 1+2+3+3+7 = 166. 알고리즘 비교
| 항목 | Kruskal | Prim (heapq) |
|---|---|---|
| 시간 복잡도 | O(E log E) | O((V+E) log V) |
| 공간 복잡도 | O(V + E) | O(V + E) |
| 적합 상황 | 희소 그래프 (E ≈ V) | 밀집 그래프 (E ≈ V²) |
| 구현 난이도 | 쉬움 (정렬 + Union-Find) | 보통 (heapq) |
| 정렬 필요 | 필요 | 불필요 |
예제로 보기
| 파일 | 내용 | 핵심 개념 |
|---|---|---|
| `src/01_union_find.py` | 유니온-파인드 구현 | 경로 압축, 랭크 합치기 |
| `src/02_kruskal.py` | 크루스칼 MST | 간선 정렬 + Union-Find |
| `src/03_prim.py` | 프림 MST | heapq + visited |
| `src/04_mst_applications.py` | MST 가중치, 두 번째 MST, 병목 트리 | MST 응용 |
bash
python src/01_union_find.py
python src/02_kruskal.py
python src/03_prim.py
python src/04_mst_applications.py자주 하는 실수
- **Union-Find 경로 압축 누락**: `find` 에서 재귀적으로 부모를 루트로 갱신하지 않으면 최악 O(V) → TLE 가능.
- **Kruskal 에서 V-1 간선 조기 종료 누락**: 모든 간선을 처리해도 동작하지만, V-1 개가 선택되면 즉시 종료하는 것이 효율적입니다.
- **Prim 에서 visited 체크 누락**: 힙에서 꺼낸 정점이 이미 방문했으면 건너뜁니다. `if in_mst[u]: continue`
- **무방향 그래프 단방향 입력**: MST는 무방향 그래프 문제이므로 간선을 양쪽 방향으로 모두 추가해야 합니다.
- **연결 그래프 가정**: MST는 연결 그래프에서만 정의됩니다. 비연결 그래프라면 "최소 신장 포레스트(MSF)"를 고려해야 합니다.
정리
text
MST 알고리즘 요약
━━━━━━━━━━━━━━━━━━━━━
Kruskal : O(E log E), Union-Find, 희소 그래프
Prim : O((V+E) log V), heapq, 밀집 그래프
조건 : 가중치 연결 무방향 그래프
성질 : 절단 성질, 사이클 성질
응용 : 네트워크 설계, 클러스터링, 두 번째 MST직접 해 보기
- 위 텍스트 아트 그래프를 크루스칼로 직접 손 추적해 보세요.
- 같은 그래프를 프림으로도 풀어 보세요 (결과는 동일해야 합니다).
- 백준 1197 (최소 스패닝 트리)를 제출하여 AC를 받아 보세요.
과제
→ [homework/README.md](homework/README.md)