Notice
- 다른 코딩 문제 풀이는 코딩 문제 풀이 문서 참고
문제 정보
- 문제 링크
- 난이도: Lv.3
- 문제 유형: 탐색
풀이
거의 전형적인 최단 경로 알고리즘 문제로, dijkstra나 Floyd-Warshall 알고리즘을 사용하면 된다.
정확성 뿐만 아니라 효율성 테스트도 있는 문제지만, n이 최대 200이기 때문에 Floyd-Warshall로도 풀 수 있다.
코딩 문제를 풀 때 초당 연산 횟수는 1000만에서 3000만 정도로 고려해서 시간 복잡도를 생각하면 된다는데1, Floyd-Warshall 알고리즘의 시간 복잡도는 으로 연산을 최대 800만번 수행하기 때문이다.
그렇기에 실제 코딩 테스트 환경이었다면 dijkstra가 더 효율적일지언정 구현이 간단한 Floyd-Warshall 알고리즘이 좋을 것 같다.
코드
Floyd-Warshall 알고리즘
import java.util.*;
class Solution {
public int solution(int n, int s, int a, int b, int[][] fares) {
final int MAX_COST = 200 * 100000 + 1;
int[][] cost = new int[n+1][n+1];
for (int i = 1; i <= n; i++) {
Arrays.fill(cost[i], MAX_COST);
cost[i][i] = 0;
}
for (int i = 0; i < fares.length; i++) {
int start = fares[i][0];
int end = fares[i][1];
int fare = fares[i][2];
cost[start][end] = fare;
cost[end][start] = fare;
}
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cost[i][j] = Math.min(cost[i][j], cost[i][k] + cost[k][j]);
int answer = cost[s][a] + cost[s][b];
for (int i = 1; i <= n; i++)
answer = Math.min(answer, cost[s][i] + cost[i][a] + cost[i][b]);
return answer;
}
}dijkstra 알고리즘
import java.util.*;
class Solution {
static final int MAX_COST = 200 * 100000 + 1;
class Node implements Comparable<Node> {
int vertex;
int cost;
Node(int vertex, int cost) {
this.vertex = vertex;
this.cost = cost;
}
@Override
public int compareTo(Node o) {
return this.cost - o.cost;
}
}
public int solution(int n, int s, int a, int b, int[][] fares) {
List<List<Node>> graph = new ArrayList<>();
for (int i = 0; i <= n; i++)
graph.add(new ArrayList<>());
for(int[] fare: fares) {
int start = fare[0];
int end = fare[1];
int cost = fare[2];
graph.get(start).add(new Node(end, cost));
graph.get(end).add(new Node(start, cost));
}
int[] startA = dijkstra(n, a, graph);
int[] startB = dijkstra(n, b, graph);
int[] start = dijkstra(n, s, graph);
int answer = Integer.MAX_VALUE;
for(int i = 1; i <= n; i++)
answer = Math.min(answer, startA[i] + startB[i] + start[i]);
return answer;
}
private int[] dijkstra(int n, int start, List<List<Node>> graph) {
int[] cost = new int[n + 1];
Arrays.fill(cost, MAX_COST);
cost[start] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.offer(new Node(start, 0));
while (!pq.isEmpty()) {
Node current = pq.poll();
int curVertex = current.vertex;
int curCost = current.cost;
if (curCost > cost[curVertex]) continue;
for (Node next : graph.get(curVertex)) {
int nextVertex = next.vertex;
int nextCost = curCost + next.cost;
// 더 짧은 경로를 찾으면 갱신
if (nextCost < cost[nextVertex]) {
cost[nextVertex] = nextCost;
pq.offer(new Node(nextVertex, nextCost));
}
}
}
return cost;
}
}Footnotes
-
[되기] 코딩 테스트 합격자 되기 - 자바 편(~189 스택까지), https://wikidocs.net/232020, 2024.03.04 09:45 ↩