접근
처음에 보았을 때는 문제가 잘 이해되지 않았는데, 고속도로가 없는 구간은 길이의 차이만큼 운전해서 간다는 사실을 뒤늦게 이해했다. 사실 이번 문제는 많이 헤매서 이게 괜찮은 코드인지는 잘 감이 안온다.. 다익스트라 알고리즘을 풀려고 고른 문제이지만 dp로도 풀 수 있다고 한다.
일단 이 문제에서 신경써야할 부분은 "입력으로 들어오는 지름길이 최단거리가 아닐 수도 있다"는 점이다. 그리고 지름길의 도착 지점이 d값을 넘어간다면 결국 쓸모없는 데이터이므로, 입력값을 받을 때 이 두 경우를 고려해서 처리해줬다. 그렇게 값을 저장한 후, 다익스트라 함수에서는 출발 지점을 기준으로 정렬하는 PQ를 사용했다. d의 범위를 벗어나거나 거리가 갱신되지 않는 경우는 넘어가고 나머지는 새로운 값을 넣어준다. 이 때, 지름길이 있어도 +1칸으로 이동하는게 추후에 이득인 경우도 있으므로 지름길의 여부와 상관없이 한 칸 이동한 값을 함께 넣는다. 그리고 마지막에 결과값을 출력할 때, dist 배열을 -1로 초기화했기 때문에 dist[d]에서 1을 더해주도록 했다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class BJ1446 {
static class Road implements Comparable<Road> {
int from, to, cost;
public Road(int from, int to, int cost) {
this.from = from;
this.to = to;
this.cost = cost;
}
@Override
// 출발 지점이 작은 것부터 정렬
public int compareTo(Road o) {
return this.from - o.from;
}
}
static int INF = 10001;
static ArrayList<ArrayList<Road>> graph;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
// 입력값 저장 및 초기값 설정
st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
graph = new ArrayList<>();
int[] dist = new int[INF];
for (int i = 0; i < INF; i++)
graph.add(new ArrayList<>());
Arrays.fill(dist, -1);
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
int cost = Integer.parseInt(st.nextToken());
// 도착 지점을 넘어가는 지름길은 의미 없음 & 지름길이 항상 최단인 것은 아님
if(to > d || cost >= to - from) continue;
graph.get(from).add(new Road(from, to, cost));
}
dijkstra(dist, d);
// 결과 출력(dist[0]이 -1이므로 1 증가시켜 출력)
System.out.println(dist[d] + 1);
}
static void dijkstra(int[] dist, int d){
PriorityQueue<Road> pq = new PriorityQueue<>();
pq.add(new Road(0, 0, 0));
dist[0] = -1;
while(!pq.isEmpty()){
Road cur = pq.poll();
// 범위를 벗어남
if(cur.to > d) continue;
// 거리가 갱신되지 않음
if(dist[cur.to] != -1 && dist[cur.to] < dist[cur.from] + cur.cost) continue;
// 최단 거리 갱신
dist[cur.to] = dist[cur.from] + cur.cost;
// 지름길 이용
for(Road road : graph.get(cur.to))
pq.add(new Road(road.from, road.to, road.cost));
// 한 칸 이동
pq.add(new Road(cur.to, cur.to+1, 1));
}
}
}
'Algorithm' 카테고리의 다른 글
[백준] 14938: 서강그라운드 JAVA (0) | 2023.02.07 |
---|---|
[백준] 1916: 최소비용 구하기 JAVA, C++ (0) | 2023.02.06 |
[백준] 18352: 특정 거리의 도시 찾기 JAVA (0) | 2023.02.03 |
[백준] 2812: 크게 만들기 JAVA (0) | 2023.01.31 |
[백준] 1715: 카드 정렬하기 JAVA (0) | 2023.01.30 |