← 알고리즘 강의 목록으로
🛣️
고급 그래프
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 = 16

6. 알고리즘 비교

항목KruskalPrim (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`프림 MSTheapq + 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

자주 하는 실수

  1. **Union-Find 경로 압축 누락**: `find` 에서 재귀적으로 부모를 루트로 갱신하지 않으면 최악 O(V) → TLE 가능.
  2. **Kruskal 에서 V-1 간선 조기 종료 누락**: 모든 간선을 처리해도 동작하지만, V-1 개가 선택되면 즉시 종료하는 것이 효율적입니다.
  3. **Prim 에서 visited 체크 누락**: 힙에서 꺼낸 정점이 이미 방문했으면 건너뜁니다. `if in_mst[u]: continue`
  4. **무방향 그래프 단방향 입력**: MST는 무방향 그래프 문제이므로 간선을 양쪽 방향으로 모두 추가해야 합니다.
  5. **연결 그래프 가정**: MST는 연결 그래프에서만 정의됩니다. 비연결 그래프라면 "최소 신장 포레스트(MSF)"를 고려해야 합니다.

정리

text
MST 알고리즘 요약
━━━━━━━━━━━━━━━━━━━━━
Kruskal : O(E log E), Union-Find, 희소 그래프
Prim    : O((V+E) log V), heapq, 밀집 그래프
조건    : 가중치 연결 무방향 그래프
성질    : 절단 성질, 사이클 성질
응용    : 네트워크 설계, 클러스터링, 두 번째 MST

직접 해 보기

  1. 위 텍스트 아트 그래프를 크루스칼로 직접 손 추적해 보세요.
  2. 같은 그래프를 프림으로도 풀어 보세요 (결과는 동일해야 합니다).
  3. 백준 1197 (최소 스패닝 트리)를 제출하여 AC를 받아 보세요.

과제

→ [homework/README.md](homework/README.md)

예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗