💡Problem Solving/Programmers
[프로그래머스] 합승 택시 요금 (Java)
gom20
2021. 10. 31. 23:36
문제
https://programmers.co.kr/learn/courses/30/lessons/72413
코딩테스트 연습 - 합승 택시 요금
6 4 6 2 [[4, 1, 10], [3, 5, 24], [5, 6, 2], [3, 1, 41], [5, 1, 24], [4, 6, 50], [2, 4, 66], [2, 3, 22], [1, 6, 25]] 82 7 3 4 1 [[5, 7, 9], [4, 6, 4], [3, 6, 1], [3, 2, 3], [2, 1, 6]] 14 6 4 5 6 [[2,6,6], [6,3,7], [4,6,7], [6,5,11], [2,5,12], [5,3,20], [2,4
programmers.co.kr
풀이
S지점에서 X라는 지점에 도착해서 X->A, X->B 로 갈라진다.
즉, S->X + X->A + X->B 의 최단거리를 찾으면 된다.
플로이드 와샬 알고리즘으로 시도했지만, 시간초과가 발생해서 다익스트라로 다시 풀었다.
S, A, B 에 대해 각각 모든 정점에 대한 최단 거리를 다익스트라 알고리즘으로 구한 후,
S->X + X->A + X->B 의 min값을 찾는다.
소스코드
import java.util.*;
class Edge {
int to;
int dist;
public Edge(int to, int dist){
this.to = to;
this.dist = dist;
}
}
class Info implements Comparable<Info>{
int node;
int dist;
public Info(int node, int dist){
this.node = node;
this.dist = dist;
}
@Override
public int compareTo(Info i){
return this.dist - i.dist;
}
}
class Solution {
public int n;
public ArrayList<Edge>[] edges;
public int solution(int n, int s, int a, int b, int[][] fares) {
int answer = 0;
this.n = n;
// 1. Set EdgeList
this.edges = new ArrayList[n+1];
for(int i = 0; i <= n; i++) edges[i] = new ArrayList<Edge>();
for(int i = 0; i < fares.length; i++) {
int n1 = fares[i][0];
int n2 = fares[i][1];
int dist = fares[i][2];
edges[n1].add(new Edge(n2, dist));
edges[n2].add(new Edge(n1, dist));
}
int[] distS = dijkstra(s);
int[] distA = dijkstra(a);
int[] distB = dijkstra(b);
// A와 B가 갈라지는 지점을 찾는 것임.
// S ~ 갈라지는 지점
// 갈라지는 지점 ~ A
// 갈라지는 지점 ~ B
// S, A, B에 대해 모든 정점에 대한 최단 경로를 찾은 다음에
// 세 곳과의 거리를 합했을 때 가장 최소가 되는 지점을 찾는 것.
int min = Integer.MAX_VALUE;
for(int i = 1; i <= n; i++){
if(min > distS[i] + distA[i] + distB[i]){
min = distS[i] + distA[i] + distB[i];
}
}
return min;
}
public int[] dijkstra(int s){
// 2. set Dists
int[] dist = new int[n+1];
for(int i = 0; i <= n; i++) dist[i] = Integer.MAX_VALUE;
// 3. set PriorityQueue
PriorityQueue<Info> pq = new PriorityQueue<Info>();
// 4. offer startNode
dist[s] = 0;
pq.offer(new Info(s, dist[s]));
// 5. update dist
while(!pq.isEmpty()){
Info info = pq.poll();
if(info.dist > dist[info.node]) continue;
for(Edge adj : edges[info.node]){
if(adj.dist + dist[info.node] > dist[adj.to]) continue;
dist[adj.to] = adj.dist + dist[info.node];
pq.offer(new Info(adj.to, dist[adj.to]));
}
}
return dist;
}
}