시간 그래프에서 다음 파란불까지 대기 시간을 간선 가중치로 바꾼 다익스트라
times[v] : 1번 지역에서 v까지 도달하는 최소 시간 (long 배열)t에서 period p 횡단보도를 이용할 때 도착 시각:curP = t % M (현재 주기 내 위치)
| 조건 | 대기 | 도착 시각 |
|---|---|---|
| curP == p | 0 | t + 1 |
| curP < p | p - curP | t + (p - curP) + 1 |
| curP > p | M - curP + p | t + (M - curP + p) + 1 |
import java.util.*;
import java.io.*;
public class BOJ_24042 {
static int N;
static int M;
static List<List<Crosswalk>> graph = new ArrayList<>();
static long[] times;
static class Crosswalk {
int nx;
int p;
Crosswalk (int nx, int p) {
this.nx = nx;
this.p = p;
}
}
static class Node {
int x;
long t;
Node (int x, long t) {
this.x = x;
this.t = t;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
for (int i = 0; i <= N; i++) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int nx = Integer.parseInt(st.nextToken());
graph.get(x).add(new Crosswalk(nx, i));
graph.get(nx).add(new Crosswalk(x, i));
}
times = new long[N+1];
Arrays.fill(times, Long.MAX_VALUE);
times[1] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingLong((Node n) -> n.t)
.thenComparingInt((Node n) -> n.x));
pq.add(new Node(1, 0));
while (!pq.isEmpty()) {
Node cur = pq.poll();
if (cur.t > times[cur.x]) continue;
for (Crosswalk nc : graph.get(cur.x)) {
int curP = (int)(cur.t % M);
long nt = cur.t + 1;
if (curP < nc.p) {
nt += nc.p - curP;
} else if (curP > nc.p) {
nt += (M - curP) + nc.p;
}
if (nt < times[nc.nx]) {
times[nc.nx] = nt;
pq.add(new Node(nc.nx, nt));
}
}
}
System.out.println(times[N]);
}
}
| period | 횡단보도 | 파란불 시각 |
|---|---|---|
| 0 | 1 ↔ 2 | 0, 5, 10, ... |
| 1 | 3 ↔ 4 | 1, 6, 11, ... |
| 2 | 1 ↔ 3 | 2, 7, 12, ... |
| 3 | 4 ↔ 1 | 3, 8, 13, ... |
| 4 | 2 ↔ 3 | 4, 9, 14, ... |
다익스트라 시뮬레이션
| 현재 노드 | 현재 시각 t | curP | 이동 횡단보도 | 대기 | 도착 노드 | 도착 시각 |
|---|---|---|---|---|---|---|
| 1 | 0 | 0 | 1↔2 (p=0) | 0 | 2 | 1 |
| 1 | 0 | 0 | 1↔3 (p=2) | 2 | 3 | 3 |
| 1 | 0 | 0 | 4↔1 (p=3) | 3 | 4 | 4 ✓ |
times[4] = 4 → 정답: 4
1번에서 4번으로 직접 연결된 횡단보도(4↔1, period=3)를 t=3에 이용하는 것이 최적