[백준] 1504번 - 특정한 최단 경로 (Gold 4)
업데이트:
문제 링크
문제 설명
가중치가 주어진 그래프에서 시작점, 도착점이 주어져 있다.
반드시 지나가야 하는 두 정점 V1, V2도 주어져 있다.
이 때, 시작점에서 도착점으로 가는 경로 중 V1, V2를 지나가는 최단거리를 출력한다.
불가능하다면 -1을 출력한다.
정답 코드 및 설명
다익스트라 알고리즘은 백준 1753번 - 최단경로 (Gold 4)에서 설명했다.
시작점 I, 반드시 지나가야 하는 두 정점 V1, V2, 도착점 F가 있을 때 가능한 경로는 아래의 두 가지이다.
- I - V1 - V2 - F
- V1 - I, V1 - V2, V2 - F의 최단 거리를 다익스트라 알고리즘으로 구해서 더한다.
- I - V1과 V1 - I의 거리는 같다. 주어진 그래프가 방향성이 없기 때문이다.
- I - V2 - V1 - F
- V2 - I, V2 - V1, V1 - F의 최단 거리를 다익스트라 알고리즘으로 구해서 더한다.
두 경로 중 짧은 경로의 길이가 답이 된다.
둘 모두 불가능하다면, -1을 출력한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import java.io.*;
import java.util.*;
public class BOJ1504 {
class Node implements Comparable<Node>{
int node, minDist;
Node(int node, int minDist) {
this.node = node;
this.minDist = minDist;
}
public int compareTo(Node n) {
return this.minDist - n.minDist;
}
}
final int INF = Integer.MAX_VALUE;
int n, e, v1, v2;
int[][] adj;
private void input() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
e = Integer.parseInt(st.nextToken());
adj = new int[n][n];
for(int i = 0; i < e; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken()) - 1;
int b = Integer.parseInt(st.nextToken()) - 1;
adj[a][b] = adj[b][a] = Integer.parseInt(st.nextToken());
}
st = new StringTokenizer(br.readLine());
v1 = Integer.parseInt(st.nextToken()) - 1;
v2 = Integer.parseInt(st.nextToken()) - 1;
}
// 다익스트라 알고리즘
private int[] Dijkstra(int start) {
int[] dist = new int[n];
Arrays.fill(dist, INF);
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(start, 0));
dist[start] = 0;
while(!pq.isEmpty()) {
Node curr = pq.poll();
int currNode = curr.node;
int currDist = curr.minDist;
if(dist[currNode] < currDist)
continue;
for(int i = 0; i < n; i++) {
if(adj[currNode][i] == 0)
continue;
if(dist[i] > currDist + adj[currNode][i]) {
dist[i] = currDist + adj[currNode][i];
pq.add(new Node(i, dist[i]));
}
}
}
return dist;
}
private void solution() throws IOException {
input();
int dist = INF;
int[] dist1 = Dijkstra(v1), dist2 = Dijkstra(v2);
// 1 -> v1 -> v2 -> n
if(dist1[0] != INF && dist1[v2] != INF && dist2[n-1] != INF)
dist = dist1[0] + dist1[v2] + dist2[n-1];
// 1 -> v2 -> v1 -> n
if(dist2[0] != INF && dist2[v1] != INF && dist1[n-1] != INF)
if(dist > dist2[0] + dist2[v1] + dist1[n-1])
dist = dist2[0] + dist2[v1] + dist1[n-1];
if(dist == INF) dist = -1;
print(dist);
}
private void print(int ans) throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write(ans+"");
bw.close();
}
public static void main(String[] args) throws IOException {
new BOJ1504().solution();
}
}
댓글남기기