Question
문제 해설
- 출발지점 S, 집 A와 B
- 집까지 택시를 타고 갈 때 택시 합승을 적절하게 이용하면 택시요금을 얼마나 아낄 수 있는지 계산
- 두 사람이 모두 귀가하는데 소요되는 예상 최저 택시요금은?
Solution
풀이 접근 방법
- 합승 안함 : S에서 A와 B로 각각 따로 갔을 때
- 합승 함 : S에서 일정 지점까지 같이 가고 그 이후 각자 따로 A와 B로 갈 때
정답 코드
import java.util.Arrays;
import java.util.PriorityQueue;
public class SharedTaxi {
static class Node implements Comparable<Node> {
int idx, dist;
public Node(int idx, int dist) {
this.idx = idx;
this.dist = dist;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.dist, o.dist);
}
}
static int N, INF;
static int[][] graph;
public static void main(String[] args) {
int[][] fares = new int[][] { { 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 } };
System.out.println(solution(6, 4, 6, 2, fares));
}
static int solution(int n, int s, int a, int b, int[][] fares) {
N = n;
INF = 987654321;
graph = new int[N + 1][N + 1];
for (int i = 0; i <= N; i++) {
Arrays.fill(graph[i], INF);
}
for (int[] far : fares) {
int n1 = far[0];
int n2 = far[1];
int dist = far[2];
graph[n1][n2] = dist;
graph[n2][n1] = dist;
}
int[] sDist = dijkstra(s);
int[] aDist = dijkstra(a);
int[] bDist = dijkstra(b);
int noShare = sDist[a] + sDist[b];
int share = Integer.MAX_VALUE;
for (int i = 1; i <= N; i++) {
if (sDist[i] == INF || aDist[i] == INF || bDist[i] == INF)
continue;
share = Math.min(share, sDist[i] + aDist[i] + bDist[i]);
}
return Math.min(noShare, share);
}
public static int[] dijkstra(int from) {
PriorityQueue<Node> pq = new PriorityQueue<Node>();
int[] dist = new int[N + 1];
boolean[] visited = new boolean[N + 1];
Arrays.fill(dist, INF);
dist[from] = 0;
pq.add(new Node(from, dist[from]));
while (!pq.isEmpty()) {
int here = pq.peek().idx;
int cost = pq.peek().dist;
pq.poll();
if (cost > dist[here])
continue;
for (int i = 1; i <= N; i++) {
if (graph[here][i] != INF && !visited[i]) {
if (dist[i] > (dist[here] + graph[here][i])) {
dist[i] = dist[here] + graph[here][i];
pq.add(new Node(i, dist[i]));
}
}
}
visited[here] = true;
}
return dist;
}
}