문제
그래프가 주어졌을 때, 그 그래프의 최소 스패닝 트리를 구하는 프로그램을 작성하시오.
최소 스패닝 트리는, 주어진 그래프의 모든 정점들을 연결하는 부분 그래프 중에서 그 가중치의 합이 최소인 트리를 말한다.
입력
첫째 줄에 정점의 개수 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보다 작거나 같은 데이터만 입력으로 주어진다.
출력
첫째 줄에 최소 스패닝 트리의 가중치를 출력한다.
코드
from heapq import heappop, heappush
v, e = map(int, input().split())
parent = [i for i in range(v+1)]
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(a, b):
a = find(a)
b = find(b)
if a == b:
return
if a < b:
parent[b] = a
else:
parent[a] = b
edges = []
for _ in range(e):
a, b, c = map(int, input().split())
heappush(edges, (c, a, b))
total_cost, cnt = 0, 1
while edges:
c, a, b = heappop(edges)
if find(a) != find(b): # 사이클 형성하는지 체크
union(a,b)
total_cost += c
cnt += 1
if cnt == v: # 모든 정점을 포함하는 MST 완성
break
print(total_cost)
크루스칼(Kruskal) 알고리즘을 이용하여 풀이하였다. 크루스칼 알고리즘은 매 단계에서 가장 최소의 가중치를 갖는 간선을 선택하여 그래프를 만들어나가는 알고리즘이다. 이때 사이클을 형성하는지 확인해야 하는데 이때는 union-find 알고리즘을 사용하여 루트 노드가 같은지 확인해주면 된다. 루트 노드가 같다면 이 간선을 선택하면 사이클을 형성하므로 선택하지 않고 넘어간다.
'문제풀이 > MST' 카테고리의 다른 글
[Python/파이썬] 백준 1774번 우주신과의 교감 (0) | 2023.04.07 |
---|---|
[Python/파이썬] 백준 21924번 도시 건설 (0) | 2023.04.07 |
[Python/파이썬] 백준 16398번 행성 연결 (0) | 2023.04.06 |
[Python/파이썬] 백준 1647번 도시 분할 계획 (0) | 2023.04.06 |
[Python/파이썬] 백준 1922번 네트워크 연결 (0) | 2023.04.06 |