알고리즘 문제
프로그래머스 - 합승 택시 요금 (C++)
als982001
2023. 2. 27. 16:43
https://school.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
school.programmers.co.kr
이 문제는 무지와 어피치가 어디까지 합승을 해야 가장 요금이 적게 나오는지를 구하는 문제이다. 그리고 이는 플로이드 와샬 알고리즘을 이용해 풀 수 있는 문제이다. 왜냐하면, 이 문제를 풀기 위해서는 각 노드에서 각 노드까지의 최단 거리(이 문제에서는 최소 요금)을 알아야 하는데, 플로이드 와샬 알고리즘을 이용하면 모든 노드에서 모든 노드까지의 최단 거리, 혹은 최소 요금을 계산할 수 있기 때문이다. 이 알고리즘을 이용해 각 노드 사이의 모든 최소 거리를 구한 후, 모든 경우의 최소 요금을 비교하면 된다. 이 문제를 풀기 위해 구상한 절차는 다음과 같다.
- 우선 요금을 저장할 변수(costs라는 이름의 2차원 배열)을 초기화한다. 이 때 , 출발 노드와 도착 노드가 같다면 0을, 다르다면 INF(가능한 엄청 큰 값)로 값을 설정한다.
- 주어진 fares 정보를 1번의 costs에 저장한다.
- 플로이드 와샬 알고리즘을 이용해 모든 경우의 최소 요금을 구한다.
- 시작지점 -> 무치 도착 지점 -> 어피치 도착 지점의 최소 요금과 시작 지점 -> 어피치 도착 지점 -> 무지 도착 지점의 최소 요금을 비교해 더 작은 값을 저장한다.(answer라는 이름의 변수). 이는 합승 안 하는 경우도 존재할 수 있기 때문이다. (예제 2번)
- 1번 노드부터 n번 노드를 반복하면서, 각 노드까지 합승하였을 경우의 요금과 answer의 값을 비교한 후, 더 작은 값을 answer에 저장한다. (mid까지 합승한다고 할 때, 요금은 dist[시작지점][mid] + dist[mid][무치_도착_지점] + dist[mid][어피치_도착_지점]이 된다.)
#include <string>
#include <vector>
#include <memory.h>
using namespace std;
#define MAX 201
#define INF 5000000 // 이 값을 꽤 크게 주는 게 중요하다고 생각한다
int costs[MAX][MAX];
int solution(int n, int s, int a, int b, vector<vector<int>> fares)
{
for (int from = 1; from <= n; ++from)
{
for (int to = 1; to <= n; ++to)
{
if (from == to)
costs[from][to] = 0;
else
costs[from][to] = INF;
}
}
for (int i = 0; i < fares.size(); ++i)
{
vector<int> fare = fares[i];
int nodeA = fare[0];
int nodeB = fare[1];
int cost = fare[2];
costs[nodeA][nodeB] = cost;
costs[nodeB][nodeA] = cost;
}
for (int mid = 1; mid <= n; ++mid)
{
for (int start = 1; start <= n; ++start)
{
for (int end = 1; end <= n; ++end)
{
if (costs[start][end] > costs[start][mid] + costs[mid][end])
costs[start][end] = costs[start][mid] + costs[mid][end];
}
}
}
int answer = min(costs[s][a] + costs[a][b], costs[s][b] + costs[b][a]);
for (int mid = 1; mid <= n; ++mid)
answer = min(answer, costs[s][mid] + costs[mid][a] + costs[mid][b]);
return answer;
}