메모리: 75 MB, 시간: 1.51 ms
코딩테스트 연습 > 탐욕법(Greedy)
정확성: 100.0
합계: 100.0 / 100.0
2024년 09월 03일 19:34:53
n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.
다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.
제한사항
((n-1) * n) / 2이하입니다.입출력 예
| n | costs | return |
|---|---|---|
| 4 | [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] | 4 |
입출력 예 설명
costs를 그림으로 표현하면 다음과 같으며, 이때 초록색 경로로 연결하는 것이 가장 적은 비용으로 모두를 통행할 수 있도록 만드는 방법입니다.

출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
class Solution {
public static class Edge {
int from, to;
int cost;
public Edge(int from, int to, int cost) {
super();
this.from = from;
this.to = to;
this.cost = cost;
}
@Override
public String toString() {
return "Edge [from=" + from + ", to=" + to + ", cost=" + cost + "]";
}
}
public static Edge[] edges;
public static Map<Integer, Integer> roots;
public int solution(int n, int[][] costs) {
int k = costs.length;
edges = new Edge[k];
roots = new HashMap<>();
for (int i = 0; i < n; i++)
roots.put(i, i);
for (int i = 0; i < k; i++)
edges[i] = new Edge(costs[i][0], costs[i][1], costs[i][2]);
Arrays.sort(edges, (o1, o2) -> o1.cost - o2.cost);
// kruskal
int cnt = 0;
int totalCost = 0;
for (int i = 0; i < costs.length; i++) {
if (unionFind(edges[i].from, edges[i].to)) {
totalCost += edges[i].cost;
cnt++;
}
if (cnt == n - 1)
break;
}
return totalCost;
}
public static int findRoot(int v) {
if (v == roots.get(v))
return v;
roots.put(v, findRoot(roots.get(v)));
return roots.get(v);
}
public static boolean unionFind(int a, int b) {
int rootA = findRoot(a);
int rootB = findRoot(b);
if (rootA == rootB)
return false;
roots.put(rootB, rootA);
return true;
}
}