[백준 13418 : JAVA] 학교 탐방하기 / MST
문제


풀이
기본 형태의 MST 문제다. 다만, 최소뿐만 아니라 최대 스패닝 트리도 구해야한다는 조건이 추가되었다.
오름차순 우선순위 큐와 내림차순 우선순위 큐 2개에 간선 정보를 담아 해결했다.
코드
import java.io.*; import java.util.*; public class Main { private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); private static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); private static int N, M; private static Queue<Node> ascendQueue = new PriorityQueue<>(); private static Queue<Node> descendQueue = new PriorityQueue<>((v1, v2) -> v2.weight - v1.weight); private static int[] parents; static class Node implements Comparable<Node> { int v1, v2, weight; public Node(int v1, int v2, int weight) { this.v1 = v1; this.v2 = v2; this.weight = weight; } @Override public int compareTo(Node o) { return weight - o.weight; } } public static void main(String[] args) throws IOException { StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); // 건물의 수 (=정점의 수) M = Integer.parseInt(st.nextToken()); // 도로의 수 (=간선의 수) parents = new int[N + 1]; // 내리막길 가중치는 1, 오르막길 가중치는 K^2 for (int i = 0; i < M + 1; i++) { // 입구와 1번 정점간의 관계가 가장 먼저 주어진다. st = new StringTokenizer(br.readLine()); int v1 = Integer.parseInt(st.nextToken()); int v2 = Integer.parseInt(st.nextToken()); int weight = Integer.parseInt(st.nextToken()); ascendQueue.add(new Node(v1, v2, weight)); descendQueue.add(new Node(v1, v2, weight)); } Arrays.fill(parents, -1); int edgeCount = 0; int maxCost = 0; while ((edgeCount <= N) && !ascendQueue.isEmpty()) { Node node = ascendQueue.poll(); if (union(node.v1, node.v2)) { edgeCount++; maxCost += node.weight; } } maxCost = (N - maxCost) * (N - maxCost); // 비용은 (오르막길 수^2) Arrays.fill(parents, -1); edgeCount = 0; int minCost = 0; while ((edgeCount <= N) && !descendQueue.isEmpty()) { Node node = descendQueue.poll(); if (union(node.v1, node.v2)) { edgeCount++; minCost += node.weight; } } minCost = (N - minCost) * (N - minCost); bw.write(maxCost - minCost + "\n"); bw.flush(); bw.close(); br.close(); } private static boolean union(int v1, int v2) { v1 = find(v1); v2 = find(v2); if (v1 != v2) { parents[v2] = v1; return true; } return false; } private static int find(int v) { if (parents[v] < 0) return v; return parents[v] = find(parents[v]); } }
'Algorithm > Baekjoon' 카테고리의 다른 글
[백준 9466 : JAVA] 텀 프로젝트 / DFS (0) | 2020.09.23 |
---|---|
[백준 11438 : JAVA] LCA 2 / 최소 공통 조상 (0) | 2020.09.11 |
[백준 2206 : JAVA] 벽 부수고 이동하기 / BFS (0) | 2020.09.08 |
[백준 9370 : JAVA] 미확인 도착지 / 다익스트라 (0) | 2020.08.28 |
[백준 11057 : C++] 오르막 수 / DP (0) | 2019.10.24 |
댓글
이 글 공유하기
다른 글
-
[백준 9466 : JAVA] 텀 프로젝트 / DFS
[백준 9466 : JAVA] 텀 프로젝트 / DFS
2020.09.23문제 풀이 이 문제는 모든 정점은 한 번씩만 탐색되어야 한다는게 핵심이다. 첫 번째 예제를 살펴보자. 가장 먼저 1번 노드부터 탐색을 진행한다. 1번 노드부터 탐색을 시작했더니 3번 노드가 사이클을 형성한다는걸 찾았다. 이게 이 문제의 포인트인데, 사이클 형성 여부를 찾기 위해 가장 쉽게 생각해볼 수 있는 방법은 다음과 같다. 처음 탐색을 시작한 노드 == 마지막으로 탐색할 노드 위의 방법으로 탐색을 진행하게 된다면 중복 탐색이 많이 발생하게 된다는 단점이 있다. 1번 노드가 사이클이 형성되지 않는단 걸 알지만, 다음 2번 노드의 탐색을 진행할 때 2 - 1 -3 으로 1번과 똑같은 탐색을 진행하게 된다. 다음 그림을 보자. 조건을 아래와 같이 바꾼다. 다음 노드가 탐색 시작 노드와 같은지 -------… -
[백준 11438 : JAVA] LCA 2 / 최소 공통 조상
[백준 11438 : JAVA] LCA 2 / 최소 공통 조상
2020.09.11문제 풀이 LCA(Lowest Common Acestor_최소 공통 조상) 알고리즘을 사용하는 기본 유형의 문제다. 해당 문제에서 주의깊게 봐둬야할 건 각 노드의 2^i 번 째 조상노드를 테이블에 저장하기 위해 DP를 사용한 점화식이다. DFS 탐색을 통해 각 노드별 depth를 구해 배열에 저장하고, 각 노드의 첫 번째 조상노드를 parent 배열에 담는다. (DP 사전준비) DP 알고리즘을 통해 각 노드의 모든 2^i 번 째 조상노드를 구해 parent 배열에 저장한다. LCA(a, b)에서 a와 b의 깊이를 맞춘 후, 차례로 2^i 번 째 조상노드를 구해가며 최소 공통 조상을 찾는다. 위의 2번을 보면 DP를 통해 각 노드의 2^i 번 째 조상노드를 저장한다고 되어 있는데, 해당 코드를 보자. fo… -
[백준 2206 : JAVA] 벽 부수고 이동하기 / BFS
[백준 2206 : JAVA] 벽 부수고 이동하기 / BFS
2020.09.08문제 풀이 2차원 평면이 주어질 때, 출발지에서 목적지까지의 단순 거리를 BFS 탐색을 통해 알아내는 문제다. 가장 기본적인 BFS 문제 유형에서 1개의 벽을 부술 수 있다는 한 가지 조건이 추가된 문제다. 추가된 위 조건으로 인해 생긴 고려사항은 다음과 같다. 기존에 (x, y) 좌표와 거리 값을 담는 distance 변수 외에 해당 좌표로 오기까지 벽을 부순 횟수를 저장할 변수가 하나 더 필요하다. 탐색할 다음 좌표가 벽이더라도 지금까지 벽을 부순 횟수가 0이라면 벽을 부수고 지날 수 있다. 기존에는 visited 변수를 통해 해당 좌표를 방문했는지만 체크했지만, 여기선 추가로 방문 여부 + 벽을 부순 횟수를 체크해야한다. 따라서, visited 변수를 boolean 타입이 아닌 int 타입으로 선언… -
[백준 9370 : JAVA] 미확인 도착지 / 다익스트라
[백준 9370 : JAVA] 미확인 도착지 / 다익스트라
2020.08.28문제 풀이 최단 경로를 구하는 문제로 다익스트라 알고리즘을 이용해 풀 수 있는 문제다. 위의 예제 입력에서 첫 번째 테스트 케이스를 그래프로 시각화해보자. 특정 목적지로의 최단 경로 중특정 경로를 포함하는지를 확인하는게 문제의 포인트다. 위 케이스의 최단 경로에서 2에서 3으로 가는 경로가 포함되어 있는지 확인하기 위해 생각해볼 수 있는 방법은 두 가지다. 첫 번째, (1 -> 2 최단거리) + (2 -> 3 최단거리) + (3 -> 5 최단거리) == (1 -> 5 최단거리) 또는 (1 -> 3 최단거리) + (3 -> 2 최단거리) + (2 -> 5 최단거리) == (1 -> 5 최단거리) 위 방법은 가장 간단하게 생각해볼 수 있는 방법이지만, 다익스트라 함수를 여러 번 호출해야하기 때문에 비효율적…
댓글을 사용할 수 없습니다.