"집들이 모인 마을이 있고 아무 두 집 사이에나 케이블을 까는 가격이 정해져 있어. 모든 집에 닿는 가장 싼 배선은 뭘까? 그게 최소 신장 트리야. 그리고 가장 싸면서 안전한 간선을 탐욕적으로 집어 가면 실제로 최적의 답이 나와."
MST가 뭐고 뭐가 아닌지
가중치가 붙은 무방향 연결 그래프의 최소 신장 트리는 모든 정점을 잇는 간선 집합 중 가중치 총합이 가장 작은 거야. 간선을 정확히 V−1개 쓰지. 그래프가 연결돼 있지 않다면 MST 하나가 아니라 연결 요소마다 최소 신장 포리스트를 얻게 되고. MST는 특정한 두 노드 사이의 최단 경로가 아니라 전체 연결 비용을 최소화하는 문제라는 걸 계속 붙들고 가.
Kruskal 알고리즘: 가장 싼 간선부터
Kruskal은 아름다울 만큼 탐욕적이고, 바로 앞에서 만든 도구를 그대로 재사용해. 모든 간선을 가중치 순으로 정렬하고, 싼 것부터 넣되, 양 끝점이 이미 이어져 있는 간선은 건너뛰는 거야. 그런 간선을 넣으면 순환이 생기니까. 그리고 '이미 이어져 있나?'가 정확히 find가 답하는 질문이지. 그래서 Union-Find가 엔진이 돼. 두 끝점이 다른 집합이면 union하고, 루트가 같으면 그 간선은 건너뛰어. 간선을 V−1개 넣으면 멈추고. MST 전체가 '간선 정렬 + union-find 순환 검사'에서 툭 떨어지는 거야. 전체 비용은 정렬이 지배해서 O(E log E)고.
Prim 알고리즘: 씨앗에서 키우기
Prim은 반대 각도에서 접근해. 아무 정점 하나에서 시작해 트리를 바깥으로 키워 나가는데, 지금까지 만든 트리를 아직 안 들어온 정점에 잇는 가장 싼 간선을 반복해서 추가해. '새 정점으로 가는 가장 싼 간선'이 곧 최소 힙 질의라서, 최단 경로에 Dijkstra가 있듯 MST에는 Prim이 있는 셈이야. 둘 다 힙 트랙의 우선순위 큐 위에서 돌아가고. Kruskal은 간선 단위로 생각하고(전부 정렬해서), Prim은 자라나는 경계로 생각해(가로지르는 간선을 담은 힙으로). 어느 쪽이든 유효한 MST가 나와.
왜 여기서는 탐욕이 통할까
MST에서 탐욕이 맞는 근거는 cut property야. 어떤 cut을 가로지르는 간선 중 가중치가 가장 작은 것은 적어도 하나의 MST에 넣어도 안전하다는 거지. 다만 최솟값이 여러 개로 동점이라면 그중 특정 간선 하나가 모든 MST에 반드시 들어간다는 뜻은 아니야. 그리고 MST를 이용한 TSP 근사는 완전 그래프의 거리 함수가 삼각부등식을 만족하는 metric TSP 같은 추가 전제가 있어야만 보장이 성립해.