티스토리 뷰
반응형
백준 알고리즘 문제 1922 문제를 정리하는 포스팅입니다. 최적의 코드가 아니니 해당 코드는 참고만 하시기 바랍니다.
1. 최소신장트리 ( Minimum Spanning Tree )
이 문제는 최소 신장 트리 문제입니다. 최소 신장 트리(MST)는 그래프 알고리즘 중 하나 입니다.
최소 신장 트리(MST)는 Kruskal 알고리즘과 Prim 알고리즘이 있습니다.
이 문제는 Kruskal 알고리즘 문제로 다음과 같이 생각해볼 수 있습니다.
- 그래프의 간선들을 가중치의 오름차순으로 정렬한다.
- 정렬된 간선 리스트에서 순서대로 사이클이 생기지 않는 간선을 선택합니다.
- 비용이 낮은 순서로 간선을 선택합니다.
- 사이클이 생성되지 않는다 함은 노드-1개의 간선을 선택한다는 의미 입니다. - 선택된 간선을 현재 MST의 집합에 추가한다.
2. 코드
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
public class Main {
private static int N, M;
private static final int FROM = 0, TO = 1, COST = 2;
private static ArrayList<Integer[]> edges;
private static StringTokenizer st;
private static int[] union;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
M = Integer.parseInt(br.readLine());
edges = new ArrayList<>();
union = new int[N+1];
for(int i=1; i<N+1; i++) union[i] = i;
for(int i=0; i<M; i++) {
st = new StringTokenizer(br.readLine());
Integer[] temp = new Integer[3];
temp[FROM] = Integer.parseInt(st.nextToken());
temp[TO] = Integer.parseInt(st.nextToken());
temp[COST] = Integer.parseInt(st.nextToken());
edges.add(temp);
}
edges.sort(new Comparator<Integer[]>() {
@Override
public int compare(Integer[] o1, Integer[] o2) {
// TODO Auto-generated method stub
return o1[COST] < o2[COST] ? -1 : 1;
}
});
int select = 0, cost_sum = 0;
for(int i=0; i<M; i++) {
Integer[] edge = edges.get(i);
if(union(edge[FROM], edge[TO])) {
select++;
cost_sum += edge[COST];
}
if(select == N-1) {
break;
}
}
System.out.println(cost_sum);
}
private static boolean union(int a, int b) {
a = find(a);
b = find(b);
if(a == b) return false;
union[b] = a;
return true;
}
private static int find(int a) {
if(a == union[a]) return a;
return union[a] = find(union[a]);
}
}
전체 코드를 부분적으로 나눠 설명 드리겠습니다.
<< 정렬 코드 >>
for(int i=0; i<M; i++) {
st = new StringTokenizer(br.readLine());
Integer[] temp = new Integer[3];
temp[FROM] = Integer.parseInt(st.nextToken());
temp[TO] = Integer.parseInt(st.nextToken());
temp[COST] = Integer.parseInt(st.nextToken());
edges.add(temp);
}
edges.sort(new Comparator<Integer[]>() {
@Override
public int compare(Integer[] o1, Integer[] o2) {
// TODO Auto-generated method stub
return o1[COST] < o2[COST] ? -1 : 1;
}
});
주어진 엣지가 모두 처음에 제공되기 때문에 해당 엣지들을 모두 입력 받아 비용에 따라 오름차순으로 정렬하는 것이 중요합니다.
private static boolean union(int a, int b) {
a = find(a);
b = find(b);
if(a == b) return false;
union[b] = a;
return true;
}
private static int find(int a) {
if(a == union[a]) return a;
return union[a] = find(union[a]);
}
정렬이 되었다면 해당 엣지를 가지고 유니온 파인드를 수행하여 최소 비용으로 모든 노드들이 이어지는지 확인해줍니다. 선택된 엣지가 노드의 -1 한 만큼 선택되었다면 선택된 엣지들로 구성된 트리가 완성되었다고 판단하면 됩니다.
이 문제는 최소 신장 트리의 가장 기본이 되는 문제 같습니다. 이 문제를 이해하고 다른 문제를 심화적으로 연습해보면 이해가 빠를 것 같네요!!
반응형
'알고리즘 > 백준문제풀이' 카테고리의 다른 글
[JAVA] 백준 1644 문제 - 소수의 연속합 (0) | 2020.01.15 |
---|
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Java
- 지도학습
- k8s metrics-server running
- Node
- 노드
- 30 Day LeetCode Challenge
- 넘파이
- 파이썬
- git
- GPTGOT
- GPT서비스
- LeetCode 알고리즘 공부
- react
- LeetCode 풀이
- 파이썬 numpy
- vscode
- CHATGOT
- 머신러닝
- React 프로젝트 생성
- numpy
- k8s metrics-server
- LeetCode 30일 챌린지
- Python
- Component
- Java leetcode
- 리엑트
- 버츄얼스튜디오코드
- LeetCode 5월 챌린지
- 퍼셉트론
- 에라토스테네스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함