TIL
오늘 배운 것
https://www.acmicpc.net/problem/16118
다익스트라 응용문제, 간선이 조건에 따라 변할때 다익스트라.
import java.io.*;
import java.util.*;
public class Main {
static class Node {
int to;
int accval;
boolean isDouble;
Node(int t, int v, boolean i) {
to = t;
accval = v;
isDouble = i;
}
}
public static void main(String[] args) throws Exception {
//System.setIn(new FileInputStream("input.txt"));
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());
List<int[]>[] g = new ArrayList[N];
for (int i = 0; i < N; i++) {
g[i] = new ArrayList<>();
}
int[] foxDist = new int[N];
Arrays.fill(foxDist, Integer.MAX_VALUE);
foxDist[0] = 0;
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine(), " ");
int a = Integer.parseInt(st.nextToken()) - 1;
int b = Integer.parseInt(st.nextToken()) - 1;
int d = Integer.parseInt(st.nextToken());
g[a].add(new int[] { b, d * 2 });
g[b].add(new int[] { a, d * 2 });
}
PriorityQueue<Node> pq = new PriorityQueue<>((o1, o2) -> {
return Integer.compare(o1.accval, o2.accval);
});
pq.offer(new Node(0, 0, false));
while (!pq.isEmpty()) {
Node curr = pq.poll();
if (curr.accval > foxDist[curr.to])
continue;
for (int[] near : g[curr.to]) {
if (foxDist[near[0]] > foxDist[curr.to] + near[1]) {
foxDist[near[0]] = foxDist[curr.to] + near[1];
pq.offer(new Node(near[0], foxDist[near[0]], false));
}
}
}
// 여우 처리 완료
int[][] NodeDist = new int[2][N];
Arrays.fill(NodeDist[0], Integer.MAX_VALUE);
Arrays.fill(NodeDist[1], Integer.MAX_VALUE);
NodeDist[1][0] = 0;
pq.offer(new Node(0, 0, true)); // to accval isDouble
while (!pq.isEmpty()) {
Node curr = pq.poll();
if (curr.accval > NodeDist[curr.isDouble ? 1 : 0][curr.to])
continue;
for (int[] near : g[curr.to]) {
if (curr.isDouble) {
int i = NodeDist[0][near[0]];
if (i > curr.accval + near[1] / 2) {
NodeDist[0][near[0]] = curr.accval + near[1] / 2;
pq.offer(new Node(near[0], NodeDist[0][near[0]], false));
}
} else {
int i = NodeDist[1][near[0]];
if (i > curr.accval + near[1] * 2) {
NodeDist[1][near[0]] = curr.accval + near[1] * 2;
pq.offer(new Node(near[0], NodeDist[1][near[0]], true));
}
}
}
}
int result = 0;
for (int i = 0; i < N; i++) {
if (foxDist[i] < Math.min(NodeDist[0][i], NodeDist[1][i])) {
result++;
}
}
System.out.print(result);
}
}