https://www.acmicpc.net/problem/11779
1. 아이디어
이전 최소비용 구하기 문제에서 최소비용으로 가는 경로까지 출력하는 문제로 이전에 방문한 정점을 기록하는 before 배열을 활용해서 해결할 수 있었다.([코딩테스트 준비/백준] - [백준] 1916번 - 최소비용 구하기 [Java])
2. 문제풀이
다익스트라 알고리즘에서 최소 비용 경로가 갱신되는 순간 before 배열에서 이전에 방문했던 정점을 기록하면 이후 역순으로 조회해서 경로를 찾아갈 수 있다. 경로가 도착점부터 시작점까지 역순으로 구해지므로 이를 Stack에 담은 후 Stringbuilder와 조합해서 출력하는 방식으로 구현했다.
3. 코드
import java.io.*;
import java.util.*;
public class Main {
private static class Node implements Comparable<Node> {
int v;
int w;
public Node(int v, int w) {
this.v = v;
this.w = w;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.w, o.w);
}
}
private static final int INF = 1_000_000_000;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
int M = Integer.parseInt(br.readLine());
List<List<Node>> adj = new ArrayList<>();
for (int i = 0; i <= N; i++) {
adj.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 W = Integer.parseInt(st.nextToken());
adj.get(A).add(new Node(B, W));
}
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
System.out.println(dijkstra(start, end, N, adj));
}
private static String dijkstra(int start, int end, int N, List<List<Node>> adj) {
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(start, 0));
boolean[] visited = new boolean[1 + N];
int[] dist = new int[1 + N];
Arrays.fill(dist, INF);
dist[start] = 0;
int[] before = new int[1 + N];
while (!pq.isEmpty()) {
Node node = pq.remove();
if (node.v == end) {
StringBuilder sb = new StringBuilder();
Deque<Integer> stack = new ArrayDeque<>();
stack.push(node.v);
while (before[node.v] != 0) {
stack.push(before[node.v]);
before[node.v] = before[before[node.v]];
}
sb.append(dist[node.v]).append("\n");
sb.append(stack.size()).append("\n");
while (!stack.isEmpty()) {
sb.append(stack.pop()).append(" ");
}
return sb.toString();
}
if (visited[node.v]) continue;
visited[node.v] = true;
for (Node next : adj.get(node.v)) {
if (visited[next.v]) continue;
if (dist[next.v] > dist[node.v] + next.w) {
dist[next.v] = dist[node.v] + next.w;
pq.add(new Node(next.v, dist[next.v]));
before[next.v] = node.v;
}
}
}
return null;
}
}
4. 후기
'코딩테스트 준비 > 백준' 카테고리의 다른 글
[백준] 11444번 - 피보나치 수 6 [Java] (0) | 2025.02.02 |
---|---|
[백준] 4485번 - 녹색 옷 입은 애가 젤다지? [Java] (0) | 2025.02.01 |
[백준] 1916번 - 최소비용 구하기 [Java] (0) | 2025.02.01 |
[백준] 1504번 - 특정한 최단 경로 [Java] (0) | 2025.02.01 |
[백준] 1753번 - 최단경로 [Java] (0) | 2025.02.01 |