그래프가 주어졌을 때, 그 그래프의 최소 스패닝 트리를 구하는 프로그램을 작성하시오.
최소 스패닝 트리는, 주어진 그래프의 모든 정점들을 연결하는 부분 그래프 중에서
그 가중치의 합이 최소인 트리를 말한다.
첫째 줄에 정점의 개수 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보다 작거나 같은 데이터만 입력으로 주어진다.
첫째 줄에 최소 스패닝 트리의 가중치를 출력한다.
크루스칼 알고리즘을 활용한 풀이
import sys import heapq # 정점(V)과 간선(E)의 개수를 입력 받음 V, E = map(int, input().rstrip().split(" ")) # 그래프를 표현할 리스트 초기화 graph = [] # E개의 간선 정보를 입력 받음 for _ in range(E): start, end, weight = map(int, input().rstrip().split(" ")) # 간선 정보를 가중치를 기준으로 힙에 저장 heapq.heappush(graph, (weight, start, end)) # union 연산 함수 def union(start, end, parent): start_root = find(start, parent) # 시작 노드의 root 찾기 end_root = find(end, parent) # 끝 노드의 root 찾기 # 작은 root가 큰 root를 가리키도록 union if start_root < end_root: parent[end_root] = start_root # root의 부모를 갱신 else: parent[start_root] = end_root # root의 부모를 갱신 # find 연산 함수 (재귀적으로 root 찾기) def find(cur, parent): if parent[cur] == cur: return cur else: return find(parent[cur], parent) # 크루스칼 알고리즘 함수 def kruskal(V, E, graph): answer = 0 # 각 노드의 부모 노드 정보를 저장하는 리스트 초기화 parent = [V for V in range(V + 1)] # 그래프에 있는 모든 간선에 대해서 검사 while graph: weight, start, end = heapq.heappop(graph) # 가장 가중치가 작은 간선 추출 # 두 노드의 root가 같으면 사이클 발생 if find(start, parent) == find(end, parent): # 사이클 확인 continue # 사이클이 발생하지 않으면 MST에 포함 answer += weight union(start, end, parent) print(answer) # 최소 스패닝 트리의 가중치 출력 def solution(V, E, graph): kruskal(V, E, graph) solution(V, E, graph)
좋은 글 감사합니다. 자주 방문할게요 :)