문제 출처
1. 문제설명
- N개의 도시가 있고 도시 간 이동 시 비용이 발생한다.
- 시작점과 도착점이 주어졌을 때 최단 경로를 구하라
- 문제 분류
2. 알고리즘 설계
- 평범한 다익스트라 문제라고 생각했지만, 엄청나게 맞왜틀을 시전했었다.
- 그 이유는, 방문해보지 않아도 최단 경로가 아닌 지점에 대한 예외 처리였다.
- 현재 비용이 최소 비용보다 작으면 방문할 필요가 없다.
if(cur.cost > dist[cur.node]) continue;
- 이 예외만 잘 처리해주면, 일반적인 다익스트라 문제랑 똑같다!
- 경로 순서 저장
- 이건 어쩔 수 없이 추가 배열을 사용해야 한다.
- 우선순위 큐에 넣을 때(값을 갱신할 때)마다 이전 위치를 업데이트 해준다.
3. 전체 코드
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int INF = 987654321, SZ = 1002;
int n, m, src, dest;
vector<pii> adj[SZ];
int dist[SZ], route[SZ];
void dijkstra() {
priority_queue<pii> pq;
pq.push({ 0, src });
dist[src] = 0;
while (!pq.empty()) {
pii cur = pq.top();
pq.pop();
if(cur.first > dist[cur.second]) continue;
for(pii nxt : adj[cur.second]) {
int next = nxt.first;
int nc = cur.first + nxt.second;
if(dist[next] > nc) {
pq.push({nc, next});
dist[next] = nc;
route[next] = cur.second;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m;
for (int a, b, c; m--;) {
cin >> a >> b >> c;
adj[a].push_back({ b, c });
}
fill(dist, dist + n + 1, INF);
cin >> src >> dest;
dijkstra();
cout << dist[dest] << '\n';
vector<int> res;
while(dest != 0) {
res.push_back(dest);
dest = route[dest];
}
cout << res.size() << '\n';
for(auto it = res.rbegin(); it != res.rend(); it++)
cout << (*it) << ' ';
return 0;
}