프로그래머스 등급3 - 섬 연결하기

섬 연결하기 문제 바로 가기

풀이 날짜: 2026-05-01

baekjoon 알고리즘 문제 풀이

풀이 코드


def solution(n, costs):
    
    def find_parent(parent,x):
        if parent[x] != x:
            parent[x] = find_parent(parent, parent[x])
        return parent[x]
    
    def union_parent(parent,a,b):
        a = find_parent(parent,a)
        b = find_parent(parent,b)
        if a < b:
            parent[b] = a
        else:
            parent[a] = b
    
    parent = [0] * n
    
    for i in range(n):
        parent[i] = i
        
    costs.sort(key=lambda x:x[2])
    
    answer = 0
    
    for a,b,cost in costs:
        if find_parent(parent,a) != find_parent(parent,b):
            union_parent(parent,a,b)
            answer += cost
    
    return answer
        
    

문제 핵심

처음에는 DFS나 플로이드 워셜처럼 “연결 여부”나 “최단 거리”를 구하는 방식으로 접근하려고 했다. 하지만 이 문제는 단순히 섬이 연결되어 있는지를 확인하는 문제가 아니라, 모든 섬을 연결하면서 총 비용의 합이 최소가 되도록 해야 하는 문제였다. 따라서 핵심은 “최소 비용으로 전체를 연결”하는 것이고, 이는 최소 신장 트리(MST) 문제라는 것을 알게 되었다.


접근 방법 (아이디어)

이 문제에서는 비용이 가장 작은 다리부터 선택해 나가는 Kruskal 알고리즘을 사용했다. 다만 무조건 비용이 작은 다리를 선택하면 안 되고, 이미 연결된 섬끼리 다시 연결하면 사이클이 생기므로 이를 방지해야 했다. 따라서 두 섬의 부모 노드를 확인해 아직 같은 그룹이 아닐 때만 연결하도록 구현했다.


Union-Find 사용 이유

사이클 여부를 효율적으로 판단하기 위해 Union-Find(Disjoint Set) 자료구조를 사용했다. find_parent() 함수는 특정 노드가 어떤 그룹에 속해 있는지 확인하는 역할을 하고, union_parent() 함수는 서로 다른 그룹일 경우 하나의 그룹으로 합치는 역할을 한다. 이를 통해 이미 연결된 섬인지 빠르게 판별할 수 있었다.


비용 기준 정렬이 중요한 이유

Kruskal 알고리즘의 핵심은 “가장 비용이 적은 다리부터 선택”하는 것이다. 따라서 costs.sort(key=lambda x: x[2])를 사용해 비용 기준으로 오름차순 정렬했다. 이후 가장 싼 다리부터 확인하면서, 아직 연결되지 않은 섬일 경우에만 선택해 총 비용을 누적했다.


구현 과정에서 헷갈렸던 점

이 문제가 최단 거리 문제가 아니라 최소 신장 트리 문제라는 점을 이해하기 전까지는 플로이드 워셜이나 DFS로 접근하려고 했는데, 문제의 목적 자체가 다르다는 것을 깨닫고 Kruskal 방식으로 수정했다.