-
[KOITP] 고속도로 건설자료구조 및 알고리즘/문제풀이 2017. 1. 16. 07:57
출 처 : http://koitp.org/problem/SDS_PRO_10_4/read/
시간 제한 메모리 제한 제출 횟수 정답 횟수 (비율) 정답자 수 2.0 초 512 MB 724 211 (29%) 156 < Comment >
최소신장트리(MST) 로 푸는 문제라고 듣고 풀었음에도 유니온 파인드를 잘못 구현해서 꽤 시간이 걸렸습니다. Kruskal 알고리즘을 이용하여 풀이하였는데, 기본 컨셉은 코스트별로 모두 정렬한 뒤에, 앞에서부터 경로가 이어져있지 않을 경우를 유니온 파인드로 체크해, 경로가 이어져 있지 않을 경우에만 코스트를 더해주는 방식이었습니다. 기본적으로 앞의 것과 같은 그룹이 되면 사이클이 생기게되어, 사이클이 생기지 않는 경우보다 무조건 코스트가 높아지기 때문입니다.
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.StringTokenizer; public class MST { public static int N = 0; public static int M = 0; public static ArrayList<Road> arr = null; public static int unionFind[] = null; public static class Road { int from = 0; int to = 0; int coast = 0; public Road(int from, int to, int coast) { this.from = from; this.to = to; this.coast = coast; } public int getFrom() { return this.from; } public int getCoast() { return this.coast; } public int getTo() { return this.to; } } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); N = Integer.parseInt(br.readLine()); M = Integer.parseInt(br.readLine()); arr = new ArrayList<>(); unionFind = new int[N + 1]; for (int i = 1 ; i <= N ; i++) { unionFind[i] = i; } StringTokenizer st = null; int s, e, c; for (int i = 0 ; i < M ; i++) { st = new StringTokenizer(br.readLine()); s = Integer.parseInt(st.nextToken()); e = Integer.parseInt(st.nextToken()); c = Integer.parseInt(st.nextToken()); arr.add(new Road(s, e, c)); arr.add(new Road(e, s, c)); } Collections.sort(arr, new Comparator<Road>() { @Override public int compare(Road arg0, Road arg1) { if (arg0.getCoast() < arg1.getCoast()) return -1; else if (arg0.getCoast() == arg1.getCoast()) return 0; else return 1; } }); int coastSum = 0; for (Road road : arr) { int from = road.getFrom(); int to = road.getTo(); if (find(from) != find(to)) { union(from, to); coastSum += road.getCoast(); } } bw.write("" + coastSum); bw.flush(); bw.close(); } public static void union(int num1, int num2) { int root1 = find(num1); int root2 = find(num2); unionFind[root2] = root1; } public static int find(int num) { if (unionFind[num] == num) return num; return unionFind[num] = find(unionFind[num]); } }