D+49 탐욕법-섬 연결하기

초록귤·2025년 2월 15일
1

100일프로젝트

목록 보기
41/42
post-thumbnail

문제

문제 설명
n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.

다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.

제한사항

섬의 개수 n은 1 이상 100 이하입니다.
costs의 길이는 ((n-1) * n) / 2이하입니다.
임의의 i에 대해, costs[i][0] 와 costs[i][1]에는 다리가 연결되는 두 섬의 번호가 들어있고, costs[i][2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다.
같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다.
모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.
연결할 수 없는 섬은 주어지지 않습니다.
입출력 예

n costs return
4 [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] 4

풀이

[섬1,섬2,섬1과 섬2를 연결할 때 드는 비용]
최소의 비용으로 모든 섬이 서로 통행 가능하도록 return 최소 비용 
최소 신장 트리(Minimum Spanning Tree, MST)를 구하는 대표적인 문제

1.문제 해결 접근 방법

  • Kruskal 알고리즘 사용

모든 간선을 비용 기준으로 오름차순 정렬
Union-Find 자료구조를 사용하여 사이클 형성 방지
가장 낮은 비용의 간선부터 선택하여 MST 구성

  • Union-Find 구현

각 섬의 부모를 저장하는 배열 필요
Find 연산: 특정 섬의 최상위 부모를 찾음
Union 연산: 두 섬을 하나의 집합으로 합침

2. 코드

function solution(n, costs) {
    // 비용을 기준으로 오름차순 정렬(가장 적은 비용의 다리부터 선택하기 위함
    costs.sort((a, b) => a[2] - b[2]);
    
    // 부모 배열 초기화 (처음에는 자기 자신이 부모)
    // Union-Find 연산을 위한 기본 설정
    const parent = Array.from({ length: n }, (_, i) => i);
    
    // Find 연산: 경로 압축을 통한 최적화
    // 특정 섬의 최상위 부모를 찾는 연산
    // 경로 압축기법 사용으로 성능 최적화
    // 재귀적으로 부모를 찾으며 경로 압축
    function find(x) {
        if (parent[x] === x) return x;
        return parent[x] = find(parent[x]); // 경로 압축
    }
    
    // Union 연산
    // 두 섬을 하나의 집합으로 합치는 연산
    // 사이클 형성 여부 확인
    // 이미 같은 집합에 속한 경우 false 반환
    function union(a, b) {
        const rootA = find(a);
        const rootB = find(b);
        
        if (rootA !== rootB) {
            parent[rootB] = rootA;
            return true;  // 연결 성공
        }
        return false;  // 이미 연결됨
    }
    
    let totalCost = 0;  // 총 건설 비용
    let bridges = 0;    // 연결된 다리 수
    
    // Kruskal 알고리즘 구현
    // 정렬된 순서대로 다리 건설 시도 
    // n-1개의 다리가 건설되면 종료 (MST:Minimum Spanning Tree) 완성
    for (const [island1, island2, cost] of costs) {
        // 사이클을 형성하지 않는 경우에만 다리를 건설
        if (union(island1, island2)) {
            totalCost += cost;
            bridges++;
            
            // 모든 섬이 연결되었는지 확인
            if (bridges === n - 1) break;
        }
    }
    
    return totalCost;
}

3. 시간 복잡도

  • 정렬: O(ElogE) (E는 간선의 수)
  • Union-Find연산 : O(a(N)) (a는 애커만 함수의 역함수로, 실질적으로 상수시간
  • 전체 시간 복잡도 : O(ElogE)
    이 알고리즘은 주어진 섬들을 최소 비용으로 연결하는 최적의 해를 보장합니다. 모든 섬이 연결되었는지 확인하면서, 사이클 형성을 방지하여 최소신장 트리를 구성합니다.
profile
초록색 귤이 노랑색으로 익어가듯, 실력이 익어가기 위해 노력하는 개발자 lahee입니다.

0개의 댓글

관련 채용 정보