알고리즘 & 자료구조/문제 풀이
[프로그래머스 알고리즘 고득점 Kit][그리디][Java] 섬 연결하기
수수다
2026. 8. 15. 18:33
https://school.programmers.co.kr/learn/courses/30/lessons/42861
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
크루스칼 알고리즘을 사용해 최소 신장 트리를 만든다.
- 모든 다리를 비용 기준으로 오름차순 정렬한다.
- 비용이 작은 다리부터 확인한다.
- 두 섬의 대표가 다르면 사이클이 발생하지 않으므로 연결한다.
- 해당 다리의 비용을 minCost에 더하고 두 집합을 합친다.
Union-Find
- find(): 섬이 속한 집합의 대표를 찾고 경로를 압축한다.
- union(): 서로 다른 두 집합을 하나로 합친다.
- p[x] < 0이면 x가 해당 집합의 대표이다.
시간복잡도
- 다리 정렬: O(E log E)
- Union-Find: 약 O(E)
- 전체: O(E log E)
import java.util.*;
class Solution {
int N; //섬의 개수
int[] p;
ArrayList<Bridge> bridges;
class Bridge {
int u;
int v;
int c;
Bridge(int u, int v, int c) {
this.u = u;
this.v = v;
this.c = c;
}
}
public int solution(int n, int[][] costs) {
N = n;
p = new int[N+1];
Arrays.fill(p, -1);
bridges = new ArrayList<>();
for(int i=0; i<costs.length; i++) {
int u = costs[i][0];
int v = costs[i][1];
int c = costs[i][2];
bridges.add(new Bridge(u, v, c));
}
bridges.sort((b1, b2) -> {
return Integer.compare(b1.c, b2.c);
});
int minCost = 0;
for(Bridge bridge: bridges) {
int u = bridge.u;
int v = bridge.v;
int c = bridge.c;
if(find(u) != find(v)) {
minCost += c;
union(u, v);
}
}
return minCost;
}
public int find(int x) {
if(p[x] < 0) return x;
return p[x] = find(p[x]);
}
public void union(int x, int y) {
int u = find(x);
int v = find(y);
if(u == v) return;
if(p[u] > p[v]) {
int t = u;
u = v;
v = t;
}
if(p[u] == p[v]) p[u]--;
p[v] = u;
}
}
