문제
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의 비용이 주어지지 않습니다.
- 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.
- 연결할 수 없는 섬은 주어지지 않습니다.
풀이
Greedy 알고리즘을 활용한 크루스칼알고리즘을 이용하여 문제를 풀 수 있다.
https://conpulake.tistory.com/107
위 문제와 같은 방식으로 해결하면 된다.
Union-Find 알고리즘을 이용하여 크루스칼알고리즘을 풀면 된다.
<전체코드>
import java.util.*;
class Solution {
static class vertex implements Comparable<vertex>{
int u;
int v;
int weight;
vertex(int u, int v, int weight){
this.u = u;
this.v = v;
this.weight = weight;
}
@Override
public int compareTo(vertex v){
return this.weight - v.weight;
}
}
static int[] parent;
public int solution(int n, int[][] costs) {
int answer = 0;
parent = new int[n];
for(int i = 0 ; i < n ; i++){
parent[i] = i;
}
PriorityQueue<vertex> pq = new PriorityQueue<vertex>();
for(int i = 0 ; i < costs.length ; i++){
pq.add(new vertex(costs[i][0], costs[i][1], costs[i][2]));
}
while(!pq.isEmpty()){
vertex top = pq.poll();
int a = find(top.u);
int b = find(top.v);
if(a == b){
continue;
}
union(a,b);
answer += top.weight;
}
return answer;
}
static int find(int a){
if(parent[a] == a){
return a;
}
return parent[a] = find(parent[a]);
}
static void union(int a, int b){
int aRoot = find(a);
int bRoot = find(b);
if(aRoot != bRoot){
parent[aRoot] = b;
}
return;
}
}
'알고리즘 공부 > 탐욕알고리즘(Greedy)' 카테고리의 다른 글
[백준] 1461 도서관 (0) | 2021.08.22 |
---|---|
[프로그래머스] 단속카메라 (0) | 2021.06.07 |
[프로그래머스] 조이스틱 (0) | 2021.05.27 |
백준 1744 (수 묶기) (0) | 2021.01.22 |
백준 2873 (롤러코스터) (0) | 2021.01.21 |