[백준] 1197번: 최소 스패닝 트리 - 크루스칼 과정 설명

Narcoker·2023년 8월 9일
0

코딩테스트

목록 보기
128/150

문제

그래프가 주어졌을 때, 그 그래프의 최소 스패닝 트리를 구하는 프로그램을 작성하시오.

최소 스패닝 트리는, 주어진 그래프의 모든 정점들을 연결하는 부분 그래프 중에서
그 가중치의 합이 최소인 트리를 말한다.

입력

첫째 줄에 정점의 개수 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)
profile
열정, 끈기, 집념의 Frontend Developer

1개의 댓글

comment-user-thumbnail
2023년 8월 9일

좋은 글 감사합니다. 자주 방문할게요 :)

답글 달기