2021 카카오 신입공채 1차 온라인 코딩 테스트 for Tech developers 문제해설
그래프에서 최단 경로를 구하는 “dijkstra 알고리즘”, 또는 “Floyd-Warshal 알고리즘”을 사용하면 풀 수 있는 문제입니다.
이중 플로이드 알고리즘을 사용하여서 문제를 푼다고 가정하면, 다음과 같이 모든 지점 사이의 최저 예상 택시요금을 구할 수 있습니다.
d[i][j] = i번 지점에서 j번 지점까지 갈 때의 최저 예상 택시요금
그 다음, 다음과 같이 루프를 돌면서 최솟값을 찾아주면 됩니다.
문제에서 요구하는 답 = min(d[s][k] + d[k][a] + d[k][b]) (단, k = 1 ~ n)
import Foundation
func solution(_ n:Int, _ s:Int, _ a:Int, _ b:Int, _ fares:[[Int]]) -> Int {
var result = 999999
struct Route{
var myNum: Int
var neighborNum: [Int]
var cost: [Int]
}
var routeArr: [Route] = []
for i in 1...n{
routeArr.append(Route(myNum: i, neighborNum: [], cost: []))
}
for i in fares{
routeArr[i[0]-1].neighborNum.append(i[1])
routeArr[i[0]-1].cost.append(i[2])
routeArr[i[1]-1].neighborNum.append(i[0])
routeArr[i[1]-1].cost.append(i[2])
}
var minCost = 0
func dfs(_ start: Int, _ end: Int, _ beforeNum: [Int], _ cost: Int){
if start == end {
if minCost > cost {
minCost = cost
}
return
}
else if cost >= minCost{
return
}
else {
let route = routeArr[start-1]
let routeCnt = route.neighborNum.count
var cost = cost
var beforeNum = beforeNum
for i in 0..<routeCnt{
if !beforeNum.contains(route.neighborNum[i]){
beforeNum.append(route.neighborNum[i])
dfs(route.neighborNum[i], end, beforeNum, cost + route.cost[i] )
beforeNum.removeLast()
}
}
}
}
// 최소를 찾아야됨
for i in 1...n{
var costStoI = 0 // S에서 I로의 최소
minCost = 999999
if i != s {
dfs(s, i, [s], costStoI)
costStoI = minCost
}
var costItoA = 0 // I에서 A로의 최소
minCost = 999999
if i != a {
dfs(a, i, [a], costItoA)
costItoA = minCost
}
var costItoB = 0 // I에서 B로의 최소
minCost = 999999
if i != b {
dfs(b, i, [b], costItoB)
costItoB = minCost
}
let sum = costStoI + costItoA + costItoB
if result > sum && sum != 0{
result = sum
}
}
return result
}
import Foundation
func solution(_ n:Int, _ s:Int, _ a:Int, _ b:Int, _ fares:[[Int]]) -> Int {
var result = 0
var node: [[Int]] = []
// 자기 자신은 0 그렇지 않으면 무한으로 초기화
for i in 0...n{
var arr: [Int] = []
for _ in 0...n{
arr.append(999999);
}
node.append(arr)
node[i][i] = 0
}
// fares에 있는 비용으로 초기화
for i in fares{
node[i[0]][i[1]] = i[2]
node[i[1]][i[0]] = i[2]
}
// Floyd-Warshal 알고리즘
for k in 1...n{ // 거쳐가는 node
for i in 1...n{
for j in 1...n{
if node[i][j] > node[i][k] + node[k][j]{ // i->j로 가는 비용과 i -> k -> j 즉, k를 거쳐가는 비용을 비교
node[i][j] = node[i][k] + node[k][j]
}
}
}
}
// s에서 a + s에서 b
result = node[s][a] + node[s][b];
for i in 1...n{
// s에서 i + i에서 a + i에서 b의 최소 비용을 구해준다.
result = min(result, node[s][i] + node[i][a] + node [i][b])
}
return result
}