https://www.acmicpc.net/problem/1238
N개의 숫자로 구분된 마을에 한 명씩 학생이 살고 있다.N명의 학생이 X번 마을에 모여서 파티를 벌이기로 했다.M개의 단방향 도로들이 있고 i번째 길을 지나는데 Ti의 시간을 소비한다.N명의 학생들 중 오고 가는데 가장 많은 시간을 소비하는 학생을 출력하라.Dijkstra(다익스트라) 문제
각 마을의 학생들이 갈 수 있는 도로를 통해 X번에 도착한 후, X번 마을에서 다시 자신들의 마을로 돌아오는 최단 경로를 구하는 문제입니다.
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());
x = Integer.parseInt(st.nextToken());
map = new ArrayList<>();
rev = new ArrayList<>();
for (int i = 0; i <= n; i++) {
map.add(new ArrayList<>());
rev.add(new ArrayList<>());
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
map.get(u).add(new Node(v, w));
rev.get(v).add(new Node(u, w));
}
X로 가는 최단 경로와 X에서 다시 마을로 돌아오는 배열을 각각 만들어 줍니다. static class Node implements Comparable<Node> {
int idx, cost;
Node (int idx, int cost) {
this.idx = idx;
this.cost = cost;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.cost, o.cost);
}
}
private static int[] dijkstra(List<ArrayList<Node>> g, int start) {
int[] dist = new int[n+1]; // 각 점까지의 거리
Arrays.fill(dist, INF); // 최단 경로를 찾기 위해 최댓값으로 초기화
dist[start] = 0; // 시작 지점은 0
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(start, 0)); // 시작 노드, 이동거리 0
while (!pq.isEmpty()) {
Node cur = pq.poll();
int u = cur.idx; // 큐에서 뽑은 시작 노드
int d = cur.cost; // 노드에 대한 이동거리
if (dist[u] < d) continue; // 만약 큐에서 나온 노드까지의 거리가 d보다 짧다면 탐색은 하지 않아도 됨
// 인접 노드 탐색
for (Node nxt : g.get(u)) {
int v = nxt.idx; // 도착 노드
int w = nxt.cost; // 해당 노드까지의 거리
// 현재 저장된 v까지의 거리가 u를 경유한 거리보다 길다면 길이 업데이트
if (dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
pq.add(new Node(v, dist[v]));
}
}
}
return dist;
}
int[] start = dijkstra(rev, x); // i -> x
int[] end = dijkstra(map, x); // x -> i
x까지의 거리와x에서 시작점까지의 거리를 저장합니다. int answer = 0;
for (int i = 1; i <= n; i++) {
if (start[i] == INF || end[i] == INF) continue;
answer = Math.max(answer, start[i] + end[i]);
}
System.out.println(answer);
import java.util.*;
import java.io.*;
public class Main {
static class Node implements Comparable<Node> {
int idx, cost;
Node (int idx, int cost) {
this.idx = idx;
this.cost = cost;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.cost, o.cost);
}
}
static int n, m, x, answer;
static List<ArrayList<Node>> map, rev;
static final int INF = 1_000_000_000;
private static int[] dijkstra(List<ArrayList<Node>> g, int start) {
int[] dist = new int[n+1];
Arrays.fill(dist, INF);
dist[start] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(start, 0));
while (!pq.isEmpty()) {
Node cur = pq.poll();
int u = cur.idx;
int d = cur.cost;
if (dist[u] < d) continue;
for (Node nxt : g.get(u)) {
int v = nxt.idx;
int w = nxt.cost;
if (dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
pq.add(new Node(v, dist[v]));
}
}
}
return dist;
}
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());
x = Integer.parseInt(st.nextToken());
map = new ArrayList<>();
rev = new ArrayList<>();
for (int i = 0; i <= n; i++) {
map.add(new ArrayList<>());
rev.add(new ArrayList<>());
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
map.get(u).add(new Node(v, w));
rev.get(v).add(new Node(u, w));
}
int[] start = dijkstra(rev, x);
int[] end = dijkstra(map, x);
int answer = 0;
for (int i = 1; i <= n; i++) {
if (start[i] == INF || end[i] == INF) continue;
answer = Math.max(answer, start[i] + end[i]);
}
System.out.println(answer);
}
}