문제 출처
1. 문제설명
- 세준이는 학교에 가기 위해서 차를 타고 D킬로미터 길이의 고속도로를 지난다.
- 고속도로에는 지름길이 있다.
- 세준이가 운전해야 하는 거리의 최솟값을 구하라.
2. 알고리즘 설계
- 가중치가 0 또는 1이 아니라, 여러개 이므로, BFS는 사용할 수 없다.
- 알고리즘 분류는 다익스트라, DP이지만,
- DP 방식으로 해결했다.
- 1부터 목적지까지 하나씩 증가시킨다.
- 증가시키다가, 해당 지점의 지름길이 있다면,
- 지름길로 가는 것과 그냥 가는 것 중 빠른 걸로 갱신한다.
3. 로직
- DP의 핵심은 점화식이므로, 점화식으로 설명하겠다.
- 아래의 코드는 지름길이 있는 지점을 방문했을 때이다.
- 지름길 없이 그냥 왔을 때의 값
- 지름길의 시작 지점 부터 가중치를 더했을 때의 값
- 비교
DP[i] = min(DP[i], min(DP[i - 1] + 1, DP[root.src] + root.weight))
4. 전체 코드
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int INF = 0x3f3f3f;
const int SZ = 10001;
int n, d;
vector<int> DP(SZ, INF);
vector<pii> v[SZ];
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> d;
for (int i = 0; i < n; i++) {
int src, dest, w;
cin >> src >> dest >> w;
v[dest].push_back({ src, w });
}
DP[0] = 0;
for (int i = 1; i <= d; i++) {
if (v[i].size() == 0) DP[i] = DP[i - 1] + 1;
else {
for (auto a : v[i])
DP[i] = min(DP[i], min(DP[i - 1] + 1, DP[a.first] + a.second));
}
}
cout << DP[d];
return 0;
}