문제
제한 시간 : 7초


핵심
다익스트라 알고리즘을 사용하여 각 문자 위치 간의 최단 경로를 찾을 수 있다.
다익스트라 알고리즘의 시간 복잡도: O((V+E)logV), 여기서 V는 노드의 수, E는 간선의 수
전체 시간 복잡도: O(N^2 log N^2)
N이 1000일 때, 대략 1000^2 * log(1000^2) ≈ 10^8 정도의 연산이 필요하므로 7초 내에 충분히 해결 가능
전체 경로는 (1,1) -> E -> L -> I -> C -> E 순서로 이동하는 최단 경로의 합이 된다.
단 E는 두 개이므로 둘 중 어느 것을 먼저 방문했을 때, 더 빠른지 고려해야 한다.
Code (Java)
import java.util.*;
class Main {
static int N;
static int[][] grid;
static int[][] dist;
static boolean[][] visited;
static int[] dr = {-1, 1, 0, 0};
static int[] dc = {0, 0, -1, 1};
static int[][] chars = new int[5][2];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
N = scanner.nextInt();
grid = new int[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
grid[i][j] = scanner.nextInt();
}
}
for (int i = 0; i < 5; i++) {
chars[i][0] = scanner.nextInt() - 1;
chars[i][1] = scanner.nextInt() - 1;
}
int minTotalDist = Integer.MAX_VALUE;
// 첫 번째 E와 두 번째 E에 대해 각각 계산
for (int firstE = 0; firstE <= 4; firstE += 4) {
int secondE = 4 - firstE;
int startToE = dijkstra(0, 0, chars[firstE][0], chars[firstE][1]);
int EtoL = dijkstra(chars[firstE][0], chars[firstE][1], chars[1][0], chars[1][1]);
int LtoI = dijkstra(chars[1][0], chars[1][1], chars[2][0], chars[2][1]);
int ItoC = dijkstra(chars[2][0], chars[2][1], chars[3][0], chars[3][1]);
int CtoE = dijkstra(chars[3][0], chars[3][1], chars[secondE][0], chars[secondE][1]);
if (startToE != -1 && EtoL != -1 && LtoI != -1 && ItoC != -1 && CtoE != -1) {
int totalDist = startToE + EtoL + LtoI + ItoC + CtoE;
minTotalDist = Math.min(minTotalDist, totalDist);
}
}
System.out.println(minTotalDist == Integer.MAX_VALUE ? -1 : minTotalDist);
}
static int dijkstra(int sr, int sc, int er, int ec) {
dist = new int[N][N];
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
Arrays.fill(dist[i], Integer.MAX_VALUE);
}
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);
pq.offer(new int[]{sr, sc, 0});
dist[sr][sc] = 0;
while (!pq.isEmpty()) {
int[] cur = pq.poll();
int r = cur[0], c = cur[1];
if (visited[r][c]) continue;
visited[r][c] = true;
if (r == er && c == ec) return dist[r][c];
for (int i = 0; i < 4; i++) {
int nr = r + dr[i];
int nc = c + dc[i];
if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;
int newDist = dist[r][c] + grid[r][c] + grid[nr][nc];
if (newDist < dist[nr][nc]) {
dist[nr][nc] = newDist;
pq.offer(new int[]{nr, nc, newDist});
}
}
}
return -1; // 도달할 수 없는 경우
}
}728x90
반응형
'CS > APS' 카테고리의 다른 글
| [Baekjoon Online Judge] 2839. 설탕 배달 (C++, Java) (0) | 2024.07.29 |
|---|---|
| [Baekjoon Online Judge] 11286. 절댓값 힙 (C++, Java) (0) | 2024.07.24 |
| [엘리스 알고리즘 코드 챌린지] Day 5. 수열 복원 (Java) (0) | 2024.07.12 |
| [엘리스 알고리즘 코드 챌린지] Day 4. 트리 위의 게임 (Java) (24) | 2024.07.11 |
| [Baekjoon Online Judge] 19951. 태상이의 훈련소 생활 (Java) (0) | 2024.07.10 |