2 분 소요

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/42861

문제 제목 : 섬 연결하기

문제 설명 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 입출력 예 설명

costs를 그림으로 표현하면 다음과 같으며, 이때 초록색 경로로 연결하는 것이 가장 적은 비용으로 모두를 통행할 수 있도록 만드는 방법입니다.

image.png

문제 풀이

import java.util.*;

// Solution 클래스 시작
class Solution {
    // solution 메소드 시작
    public int solution(int n, int[][] costs) {
        // answer 변수 초기화
        int answer = 0;
        // island 배열 초기화: 섬의 개수만큼 생성
        int[] island = new int[n];

        // 각 섬의 대표(부모)를 자기 자신으로 설정
        for (int i = 0; i < n; i++) {
            island[i] = i;
        }

        // 건설 비용을 기준으로 비용 오름차순으로 정렬
        Arrays.sort(costs, (a, b) -> Integer.compare(a[2], b[2]));

        // 모든 연결 가능한 섬 쌍을 확인하여 최소 비용으로 연결하기
        for (int i = 0; i < costs.length; i++) {
            // 두 섬의 대표가 다를 경우에만 연결하고 비용을 더함
            if (find(island, costs[i][0]) != find(island, costs[i][1])) {
                // 두 섬을 연결하고 연결 비용을 더함
                unite(island, costs[i][0], costs[i][1]);
                answer += costs[i][2];
            }
        }

        // 최소 비용 반환
        return answer;
    }
    // solution 메소드 끝

    // 대표(부모) 찾기 메소드 시작
    private int find(int[] island, int x) {
        // 현재 섬이 자신을 대표로 가질 때까지 재귀적으로 대표를 찾음
        if (island[x] == x) {
            return x;
        }
        return find(island, island[x]);
    }
    // 대표(부모) 찾기 메소드 끝

    // 두 섬을 연결하는 메소드 시작
    private void unite(int[] island, int x, int y) {
        // 두 섬의 대표(부모)를 찾음
        int a = find(island, x);
        int b = find(island, y);
        // 한 섬의 대표를 다른 섬의 대표로 변경하여 연결
        island[a] = b;
    }
    // 두 섬을 연결하는 메소드 끝
}
// Solution 클래스 끝

댓글남기기