[백준] 9370: 미확인 도착지 - JAVA
https://www.acmicpc.net/problem/1956
풀이
목적지까지 최단경로에 (g-h)나 (h-g) 도로를 거치는지 확인하는 문제이다.
목적지를 t, 출발지를 s라고 한다면 (s-t)의 거리가 (s-g) + (g-h) + (h-t), (s-h) + (h-g) + (g-t) 두 거리 중 작은 값과 같다면 g-h 도로를 지났다고 확인할 수 있다.
따라서 다익스트라 알고리즘을 사용하여 s부터의 거리 배열, g부터의 거리, h부터의 거리 3개의 배엻을 구한다.
(s-t) 거리가 다른 두 거리 중 작은 값과 같다면 출력한다.
메모리: 63248KB
시간: 676ms
언어: Java 11
코드
import java.util.*;
import java.io.*;
public class Main {
static class Node implements Comparable<Node> {
int v;
int weight;
public Node(int v, int weight) {
this.v = v;
this.weight = weight;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.weight, o.weight);
}
}
static int n;
static ArrayList<ArrayList<Node>> list;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
StringTokenizer st;
for (int tc = 0; tc < T; tc++) {
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int t = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
int s = Integer.parseInt(st.nextToken());
int g = Integer.parseInt(st.nextToken());
int h = Integer.parseInt(st.nextToken());
list = new ArrayList<>();
for (int i = 1; i <= n + 1; i++) {
list.add(new ArrayList<>());
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
list.get(a).add(new Node(b, d));
list.get(b).add(new Node(a, d));
}
int[] dist_s = dijkstra(s);
int[] dist_g = dijkstra(g);
int[] dist_h = dijkstra(h);
int[] goal = new int[t];
for (int i = 0; i < t; i++) {
goal[i] = Integer.parseInt(br.readLine());
}
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int x : goal) {
int gh = dist_s[g] + dist_g[h] + dist_h[x];
int hg = dist_s[h] + dist_h[g] + dist_g[x];
int sx = dist_s[x];
if (Math.min(gh, hg) == sx) {
pq.add(x);
}
}
while (!pq.isEmpty()) {
sb.append(pq.poll() + " ");
}
sb.append("\n");
}
System.out.println(sb);
}
private static int[] dijkstra(int st) {
int[] dist = new int[n + 1];
Arrays.fill(dist, Integer.MAX_VALUE);
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(st, 0));
dist[st] = 0;
boolean[] visit = new boolean[n + 1];
while (!pq.isEmpty()) {
Node node = pq.poll();
if (visit[node.v]) {
continue;
}
visit[node.v] = true;
for (Node next : list.get(node.v)) {
if (!visit[next.v] && dist[next.v] > dist[node.v] + next.weight) {
dist[next.v] = dist[node.v] + next.weight;
pq.add(new Node(next.v, dist[next.v]));
}
}
}
return dist;
}
}