코딩 테스트/프로그래머스
프로그래머스 - 합승 택시 요금 문제 (자바)
wellbell
2021. 3. 18. 20:30
programmers.co.kr/learn/courses/30/lessons/72413
이문제는 다익스트라 또는 플로이드 워셜 알고리즘으로 풀수 있습니다.
주의점
알고리즘으로 최단거리를 구하고 나서 경유하는 경우까지 계산 해야합니다.
1. 플로이드 워셜
import java.util.Arrays;
class Solution {
static final int MAX = 20000001; // 200 * 100000 + 1
public int solution(int n, int s, int a, int b, int[][] fares) {
int[][] dp = new int[n + 1][n + 1];
for (int i = 0; i <= n; i++) {
Arrays.fill(dp[i], MAX);
dp[i][i] = 0;
}
for(int i = 0; i < fares.length; i++) {
int start = fares[i][0];
int end = fares[i][1];
int cost = fares[i][2];
dp[start][end] = cost;
dp[end][start] = cost;
}
for(int k = 1; k < n+1; k++) {
for(int i = 1; i < n+1; i++) {
for(int j = 1; j < n+1; j++) {
dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
}
}
}
int answer = dp[s][a] + dp[s][b];
// 경유지점을 끼는경우
// s -> t t -> a + t -> b
for(int i = 1; i <= n; i++) {
answer = Math.min(answer, dp[s][i] + dp[i][a] +dp[i][b]);
}
return answer;
}
}
2. 다익스트라
import java.util.*;
class Edge implements Comparable<Edge>{
int index;
int cost;
Edge(int index, int cost){
this.index = index;
this.cost = cost;
}
@Override
public int compareTo(Edge e){
return this.cost - e.cost;
}
}
class Solution {
static final int MAX = 20000001; // 200 * 100000 + 1
static ArrayList<ArrayList<Edge>> graph;
public int solution(int n, int s, int a, int b, int[][] fares) {
int answer = Integer.MAX_VALUE;
graph = new ArrayList<>();
for(int i = 0 ; i <= n ; i ++){
graph.add(new ArrayList<>());
}
for(int[] i : fares){
graph.get(i[0]).add(new Edge(i[1], i[2]));
graph.get(i[1]).add(new Edge(i[0], i[2]));
}
int[] startA = new int[n + 1];
int[] startB = new int[n + 1];
int[] start = new int[n + 1];
Arrays.fill(startA, MAX);
Arrays.fill(startB, MAX);
Arrays.fill(start, MAX);
startA = dijkstra(a, startA);
startB = dijkstra(b, startB);
start = dijkstra(s, start);
for(int i = 1; i <= n ; i ++) answer = Math.min(answer, startA[i] + startB[i] + start[i]);
return answer;
}
static int[] dijkstra (int start, int[] costs) {
PriorityQueue<Edge> pq = new PriorityQueue<>();
pq.offer(new Edge(start, 0));
costs[start] = 0;
while (!pq.isEmpty()) {
Edge now = pq.poll();
int nIndex = now.index;
int nCost = now.cost;
if(nCost > costs[nIndex]) continue;
ArrayList<Edge> edges = graph.get(nIndex);
for (Edge edge : edges) {
int cost = costs[nIndex] + edge.cost;
if (cost < costs[edge.index]) {
costs[edge.index] = cost;
pq.offer(new Edge(edge.index, cost));
}
}
}
return costs;
}
}
플로이드 워셜(왼쪽) vs 다익스트라(오른쪽)
정확성 테스트에서는 플로이드 웨셜이 더 빠르지만
효율성으로 가니까 다익스트라가 앞도적이네요 .ㅎ