나의 풀이
import java.util.*;
class Solution {
static final int MAX = 20000001;
static ArrayList<Node>[] graph;
public int solution(int n, int s, int a, int b, int[][] fares) {
int answer = MAX;
graph = new ArrayList[n+1];
for(int i=0; i<=n; i++){
graph[i] = new ArrayList<Node>();
}
for(int[] fare : fares){
graph[fare[0]].add(new Node(fare[1], fare[2]));
graph[fare[1]].add(new Node(fare[0], fare[2]));
}
int[] startA = dijkstra(a,n);
int[] startB = dijkstra(b,n);
int[] start = dijkstra(s,n);
for(int i=1; i<=n; i++){ // S->i까지 경유하고 i->a & i->b 까지 따로간다.
answer = Math.min(answer, start[i] + startA[i] + startB[i]);
}
return answer;
}
public int[] dijkstra(int start, int n){
int[] dist = new int[n+1]; // dist[i] : start->i 까지의 거리
Arrays.fill(dist, MAX);
PriorityQueue<Node> q = new PriorityQueue<>();
q.add(new Node(start, 0));
dist[start] = 0;
while(!q.isEmpty()){
Node now = q.poll();
for(Node node : graph[now.x]){
if (dist[node.x] > now.dist + node.dist){
dist[node.x] = now.dist + node.dist;
q.add(new Node(node.x, now.dist + node.dist));
}
}
}
return dist;
}
class Node implements Comparable<Node>{
int x;
int dist;
Node(int x, int dist){
this.x = x;
this.dist = dist;
}
@Override
public int compareTo(Node e){
return this.dist - e.dist;
}
}
}
s->x 지점까지 합승한다고 가정하자.
그렇다면 (s->x 까지의 거리) + (x->a까지의 거리) + (x->b까지의 거리) 가 전체 거리의 합이 될 것이다.
즉, x지점을 1~N까지 대입해봤을 때의 최소값이 answer 이 됨을 알 수 있다.
s->x / x->a / x->b 까지의 거리를 구하기 위해서는 3번의 다익스트라를 실행해야 한다.
이때 모든 경로는 방향이 없으므로, x->a 는 a->x와 동일하다. 따라서 a,b를 출발점으로 하여 모든경로까지의 거리를 구하면 된다.
s를 시작점으로 모든 경로까지의 최단 경로 => int[] start
a를 시작점으로 모든 경로까지의 최단 경로 => int[] startA
b를 시작점으로 모든 경로까지의 최단 경로 => int[] startB
'알고리즘 > Graph 그래프' 카테고리의 다른 글
[백준] 1753번: 최단경로 - java (0) | 2023.03.02 |
---|---|
[백준] 2250번: 트리의 높이와 너비 - java (0) | 2023.02.27 |
[백준] 1167번: 트리의 지름 - java (0) | 2023.02.18 |
[백준] 3665번: 최종 순위 - 파이썬(python) (0) | 2022.10.21 |
[벡준] 2887번: 행성 터널 - 파이썬(python) (0) | 2022.10.21 |
댓글