문제풀이/백준
[백준]20010: 악덕 영주 혜유 - JAVA
빈둥벤둥
2021. 7. 7. 17:08
[백준]20010: 악덕 영주 혜유

20010번: 악덕 영주 혜유
FT온라인 게임에서 치열한 경쟁을 통해 영주가 된 혜유는 퀘스트를 받았다. 퀘스트의 내용은 자신이 관리하고 있는 마을 사이에 교역로를 건설하여 마을 간 교류를 활성화시키는 것이다. 이때,
www.acmicpc.net
풀이
🪑 MST를 구하는 활용문제이다.
문제의 조건들을 정리해보자.
- 마을간 교역로는 양방향이다.
- 모든 마을은 연결되어있다.
- 구하는 값은 MST 비용과 MST 내에서 가장 먼 노드간의 거리이다.
🔧 이제 문제 풀이 과정을 생각해 보자.
- 마을 간 교역로 정보를 입력 받은 후 MST를 구한다.
- MST를 저장해 둔 다음 MST를 내에서 DFS로 가장 먼 노드간의 거리를 구한다.
- 가장 먼 노드간의 거리를 구하기 위해선 먼저, 한 정점에서 가장 먼 노드를 구한 다음 그 정점에서 다시 가장 먼 노드를 구하면 된다. (백준 1167: 트리의 지름 참고)
🔹 MST를 구한다.
- MST알고리즘은 대표적으로 prim, kruskal이 있다. 나는 최소 간선 트리로 선택된 간선의 정보를 저장해 주기 위해 kruskal 알고리즘을 사용하였다.
🔹 DFS로 가장 먼 노드간의 거리를 구한다.
- MST로 선택된 간선들의 정보를 가지고 DFS 탐색을 진행한다.
- 가장 먼 노드 사이의 거리를 구하는 방법은 먼저 한 정점에서 가장 먼 노드를 구한 다음, 그 정점에서 다시 가장 먼 노드까지의 거리를 구하면 된다. (백준 1167: 트리의 지름 참고)
- 해당 방법으로 가장 먼 노드간의 거리를 구해주면 된다.
코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import java.util.*;
public class Main {
static PriorityQueue<Node> q = new PriorityQueue<>();
static ArrayList<Node>[] MST;
static int[] parent;
static int n, k;
static boolean[] visited;
static int max;
static int startNode;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
k = scan.nextInt();
MST = new ArrayList[n]; //최소 간선 트리 정보를 저장하는 리스트
for(int i = 0; i < n; i++) {
MST[i] = new ArrayList<>();
}
for(int i = 0; i < k; i++) {
int s = scan.nextInt();
int e = scan.nextInt();
int cost = scan.nextInt();
q.offer(new Node(s, e, cost));
}
int min = kruskal(); //MST 비용을 구한다.
max = Integer.MIN_VALUE;
visited = new boolean[n];
visited[0] = true;
dfs(0, 0);
max = Integer.MIN_VALUE;
visited = new boolean[n];
visited[startNode] = true;
dfs(startNode, 0);
System.out.println(min);
System.out.println(max);
}
public static void dfs(int node, int total) {
if(max < total) {
max = total;
startNode = node;
}
for(int i = 0; i < MST[node].size(); i++) {
Node next = MST[node].get(i);
if(!visited[next.e]) {
visited[next.e] = true;
dfs(next.e, total + next.cost);
}
}
}
public static int kruskal() {
parent = new int[n];
for(int i = 0; i < n; i++) {
parent[i] = i;
}
int min = 0;
while(!q.isEmpty()) {
Node current = q.poll();
int p1 = find(current.s);
int p2 = find(current.e);
if(p1 != p2) {
union(p1, p2);
MST[current.s].add(new Node(current.e, current.cost));
MST[current.e].add(new Node(current.s, current.cost));
min += current.cost;
}
}
return min;
}
public static int find(int a) {
if(parent[a] == a) return a;
else return parent[a] = find(parent[a]);
}
public static void union(int a, int b) {
parent[a] = b;
}
public static class Node implements Comparable<Node> {
int s;
int e;
int cost;
public Node(int s, int e, int cost) {
this.s = s;
this.e = e;
this.cost = cost;
}
public Node(int e, int cost) {
this.e = e;
this.cost = cost;
}
@Override
public int compareTo(Node n) {
return this.cost - n.cost;
}
}
}
|
cs |