https://www.acmicpc.net/problem/9370
\
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main {
public static int T, N, M, K, S, G, H;
public static int[] k;
public static int[][] graph;
public static final int INF = Integer.MAX_VALUE;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
T = Integer.parseInt(br.readLine());
for (int tc = 1; tc <= T; tc++) {
// 1. 입력받기
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
graph = new int[N + 1][N + 1];
k = new int[K];
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
graph[i][j] = INF;
}
}
st = new StringTokenizer(br.readLine());
S = Integer.parseInt(st.nextToken());
G = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
// 1-1. 도로 입력받기
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int at = Integer.parseInt(st.nextToken());
int value = Integer.parseInt(st.nextToken());
graph[from][at] = Math.min(graph[from][at], value);
graph[at][from] = Math.min(graph[at][from], value);
}
// 1-2. 도착지 입력받기
for (int i = 0; i < K; i++) {
k[i] = Integer.parseInt(br.readLine());
}
int sh = dijk(S, H);
int sg = dijk(S, G);
int gh = graph[G][H];
Arrays.sort(k);
// 2. 최단 경로 계산
for (int i = 0; i < K; i++) {
int hk = dijk(H, k[i]);
int gk = dijk(G, k[i]);
int sk = dijk(S, k[i]);
int min = INF;
// S - G - H - K
if (sg != INF && gh != INF && hk != INF) {
min = sg + gh + hk;
}
// S - H - G - K
if (sh != INF && gh != INF && gk != INF) {
min = Math.min(min, sh + gh + gk);
}
// S - K 로 가는 경로의 최솟값과 같다면 출력 아니면 continue;
if (min != INF && min == sk) {
sb.append(k[i] + " ");
}
}
// 3. 출력
sb.append("\n");
}
System.out.println(sb.toString());
}
private static int dijk(int start, int end) {
int[] min = new int[N + 1];
int[] visited = new int[N + 1];
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> Integer.compare(o1[1], o2[1]));
for (int i = 1; i <= N; i++) {
min[i] = INF;
}
min[start] = 0;
pq.offer(new int[] { start, min[start] });
while (!pq.isEmpty()) {
int[] cur = pq.poll();
int index = cur[0];
int value = cur[1];
if(visited[index] == 1) continue;
visited[index] = 1;
if(index == end) {
return value;
}
for (int i = 1; i <= N; i++) {
if (graph[index][i] != INF && min[i] > min[index] + graph[index][i]) {
min[i] = min[index] + graph[index][i];
pq.offer(new int[] { i, min[i] });
}
}
}
return min[end];
}
}
풀이 사항
풀이 일자: 2024.10.16
풀이 시간: 2시간
채점 결과: 정답
예상 문제 유형: 다익스트라
시간: 2548 ms
메모리: 204792 kb
풀이방법
다익스트라로 최단경로를 구하고 S -K 를 지나는 경로 중 G - H 를 지나는 길과 H - G 를 지나는 길을 구해서 둘중에 하나라도 최단경로와 값이 같다면 출력해주었다.
느낀점
플로이드 워샬로 풀면 시간초과난다.
'코딩테스트 > JAVA' 카테고리의 다른 글
[백준 JAVA] 4179번: 불! (0) | 2024.10.22 |
---|---|
[백준 JAVA] 17281번: ⚾ (1) | 2024.10.18 |
[백준 JAVA] 9935번: 문자열 폭발 (0) | 2024.10.13 |
[백준 JAVA] 12100번: 2048 (Easy) (0) | 2024.10.11 |
[백준 JAVA] 17143번: 낚시왕 (2) | 2024.10.10 |