https://www.acmicpc.net/problem/14938
1. 아이디어
각 지역까지의 최단 거리를 통해 아이템의 합을 구하는 문제로 다익스트라 알고리즘을 활용할 수 있고 N이 최대 100이어서 플로이드 워셜 알고리즘으로도 해결할 수 있다.
2. 문제풀이
다익스트라 알고리즘은 1번 지역부터 N번까지 각 지역을 출발지로 설정한 후 아이템의 합을 구해보며 최댓값을 찾는 방식으로 구현했고, 플로이드 워셜 알고리즘은 2차원 dp 테이블을 순회하며 각 행을 출발지로 생각하는 방식으로 구현했다.
3. 코드
import java.io.*;
import java.util.*;
public class Main_Dijkstra {
private static class Node implements Comparable<Node> {
int v;
int w;
public Node(int v, int w) {
this.v = v;
this.w = w;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.w, o.w);
}
}
private static final int INF = 1_000_000_000;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int R = Integer.parseInt(st.nextToken());
int[] items = new int[1 + N];
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= N; i++) {
items[i] = Integer.parseInt(st.nextToken());
}
List<List<Node>> adj = new ArrayList<>();
for (int i = 0; i <= N; i++) {
adj.add(new ArrayList<>());
}
for (int i = 0; i < R; i++) {
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
adj.get(u).add(new Node(v, w));
adj.get(v).add(new Node(u, w));
}
int max = Integer.MIN_VALUE;
for (int i = 1; i <= N; i++) {
max = Math.max(max, sum(i, items, N, M, adj));
}
System.out.println(max);
}
private static int sum(int start, int[] items, int N, int M, List<List<Node>> adj) {
int sum = 0;
int[] dist = dijkstra(start, N, adj);
for (int i = 1; i <= N; i++) {
if (dist[i] <= M) {
sum += items[i];
}
}
return sum;
}
private static int[] dijkstra(int start, int N, List<List<Node>> adj) {
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(start, 0));
boolean[] visited = new boolean[1 + N];
int[] dist = new int[1 + N];
Arrays.fill(dist, INF);
dist[start] = 0;
while (!pq.isEmpty()) {
Node node = pq.remove();
if (visited[node.v]) continue;
visited[node.v] = true;
for (Node next : adj.get(node.v)) {
if (visited[next.v]) continue;
if (dist[next.v] > dist[node.v] + next.w) {
dist[next.v] = dist[node.v] + next.w;
pq.add(new Node(next.v, dist[next.v]));
}
}
}
return dist;
}
}
import java.io.*;
import java.util.*;
public class Main_Floyd_Warshall {
private static final int INF = 1_000_000_000;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int R = Integer.parseInt(st.nextToken());
int[] items = new int[1 + N];
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= N; i++) {
items[i] = Integer.parseInt(st.nextToken());
}
int[][] dp = new int[1 + N][1 + N];
for (int i = 1; i <= N; i++) {
Arrays.fill(dp[i], INF);
dp[i][i] = 0;
}
for (int i = 0; i < R; i++) {
st = new StringTokenizer(br.readLine());
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
int C = Integer.parseInt(st.nextToken());
dp[A][B] = dp[B][A] = C;
}
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
}
}
}
int max = Integer.MIN_VALUE;
for (int i = 1; i <= N; i++) {
int sum = 0;
for (int j = 1; j <= N; j++) {
if (dp[i][j] <= M) {
sum += items[j];
}
}
max = Math.max(max, sum);
}
System.out.println(max);
}
}
4. 후기
- 다익스트라 알고리즘
- 플로이드 워셜 알고리즘
'코딩테스트 준비 > 백준' 카테고리의 다른 글
[백준] 2749번 - 피보나치 수 3 [Java] (0) | 2025.02.02 |
---|---|
[백준] 11780번 - 플로이드 2 [Java] (0) | 2025.02.02 |
[백준] 11404번 - 플로이드 [Java] (0) | 2025.02.02 |
[백준] 11444번 - 피보나치 수 6 [Java] (0) | 2025.02.02 |
[백준] 4485번 - 녹색 옷 입은 애가 젤다지? [Java] (0) | 2025.02.01 |