문제설명
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의 비용이 주어지지 않습니다.
- 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.
- 연결할 수 없는 섬은 주어지지 않습니다.
해결 방법
크루스칼 알고리즘으로 풀었다.
1) 두 섬을 연결하는 다리를 cost의 오름차순으로 정렬한다.
2) 가장 낮은 cost의 다리를 선택한다.
3) 다리를 연결했을 때, 사이클이 생기지않는지 union-find로 확인한다.
4) 사이클이 생기지 않는다면 두 섬을 연결하고 2번으로 돌아간다.
JAVA
package programmers;
import java.util.*;
public class p_42861 {
static int[] parent;
public static int find(int x) {
if(parent[x] == x) return x;
return find(parent[x]);
}
public static void union(int x, int y) {
x = find(x);
y = find(y);
if(x > y) parent[x] = y;
else parent[y] = x;
}
public static int solution(int n, int[][] c) {
int cost = 0;
parent = new int[n];
for(int i = 0; i < n; i++) parent[i] = i;
Arrays.sort(c, new Comparator<int[]>(){
@Override
public int compare(int[] cmp1, int[] cmp2) {
if(cmp1[2] > cmp2[2]) return 1;
else return -1;
}
});
for(int i = 0; i < c.length; i++) {
if(find(c[i][0]) != find(c[i][1])) {
cost += c[i][2];
union(c[i][0], c[i][1]);
}
}
return cost;
}
public static void main(String[] args) {
int n = 4;
int[][] c = {{0,1,1},{0,2,2},{1,2,5},{1,3,1},{2,3,8}};
int n2 = 4;
int[][] c2 = {{0,1,1},{0,2,2},{2,3,1}};
System.out.println(solution(n2, c2));
}
}
'Problem Solving > Programmers' 카테고리의 다른 글
[프로그래머스] 숫자 야구 (0) | 2020.04.06 |
---|---|
[프로그래머스] N으로 표현 (2) | 2020.04.06 |
[프로그래머스] 예산 (0) | 2020.04.04 |
[프로그래머스] 등굣길 (0) | 2020.04.04 |
[프로그래머스] 기지국 설치 (0) | 2020.04.04 |
댓글