https://www.acmicpc.net/problem/1504
1. 아이디어
시작점에서 두 점 v1, v2를 경유해서 끝점으로 가는 최단 거리를 구하는 문제로 1 -> v1 -> v2 -> N 또는 1 -> v2 -> v1 -> N 두 가지 경로에 대한 다익스트라 알고리즘으로 해결할 수 있다.
2. 문제풀이
다익스트라 알고리즘으로 각 경로마다 거리를 구하면 해결할 수 있는데 이때 연결되지 않은 두 점이어서 경로가 존재하지 않을 경우 -1을 반환했고 이를 통해 경로가 존재하는지 여부를 파악해서 경우에 맞게 출력하는 방식으로 구현했다.
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 = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int E = Integer.parseInt(st.nextToken());
List<List<Node>> adj = new ArrayList<>();
for (int i = 0; i <= N; i++) {
adj.add(new ArrayList<>());
}
for (int i = 0; i < E; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
adj.get(a).add(new Node(b, c));
adj.get(b).add(new Node(a, c));
}
st = new StringTokenizer(br.readLine());
int v1 = Integer.parseInt(st.nextToken());
int v2 = Integer.parseInt(st.nextToken());
int startToV1 = dijkstra(1, v1, N, adj);
int v1ToV2 = dijkstra(v1, v2, N, adj);
int v2ToEnd = dijkstra(v2, N, N, adj);
int path1 = startToV1 + v1ToV2 + v2ToEnd;
boolean path1IsValid = startToV1 != -1 && v1ToV2 != -1 && v2ToEnd != -1;
int startToV2 = dijkstra(1, v2, N, adj);
int v2ToV1 = dijkstra(v2, v1, N, adj);
int v1ToEnd = dijkstra(v1, N, N, adj);
int path2 = startToV2 + v2ToV1 + v1ToEnd;
boolean path2IsValid = startToV2 != -1 && v2ToV1 != -1 && v1ToEnd != -1;
if (path1IsValid && path2IsValid) {
System.out.println(Math.min(path1, path2));
} else if (path1IsValid) {
System.out.println(path1);
} else if (path2IsValid) {
System.out.println(path2);
} else {
System.out.println(-1);
}
}
private static int 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;
while (!pq.isEmpty()) {
Node node = pq.remove();
if (node.v == end) return dist[node.v];
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]));
}
}
}
return -1;
}
}
4. 후기
'코딩테스트 준비 > 백준' 카테고리의 다른 글
[백준] 11779번 - 최소비용 구하기 2 [Java] (0) | 2025.02.01 |
---|---|
[백준] 1916번 - 최소비용 구하기 [Java] (0) | 2025.02.01 |
[백준] 1753번 - 최단경로 [Java] (0) | 2025.02.01 |
[백준] 11365번 - !밀비 급일 [Java] (0) | 2025.02.01 |
[백준] 14226번 - 이모티콘 [Java] (0) | 2025.02.01 |