Notice
Recent Posts
Link
정화 코딩
[C++] 특정한 최단 경로 (백준 1504번) 본문
https://www.acmicpc.net/problem/1504
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int INTMAX = 1000000;
int n, e, v1, v2;
vector<vector<pair<int, int>>> edge;
int dijkstra(int s, int e) {
vector<int> dst(n + 1, INTMAX);
priority_queue<pair<int, int>> pq;
dst[s] = 0;
pq.emplace(0, s);
while (!pq.empty()) {
int cost = -pq.top().first;
int cur = pq.top().second;
pq.pop();
for (auto nxt: edge[cur]) {
int newcost = cost + nxt.second;
if (newcost < dst[nxt.first]) {
dst[nxt.first] = newcost;
pq.emplace(-newcost, nxt.first);
}
}
}
return dst[e];
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> e;
edge = vector<vector<pair<int, int>>>(n + 1);
for (int i = 0; i < e; i++) {
int a, b, c;
cin >> a >> b >> c;
edge[a].emplace_back(b, c);
edge[b].emplace_back(a, c);
}
cin >> v1 >> v2;
cout << dijkstra(1, v1) + dijkstra(v1, v2) + dijkstra(v2, n) << '\n';
}
다익스트라를 함수로 만들어 총 3번 호출하여 총 경로를 계산했다. 처음에 제출했던 코드이다. 도달하지 못하는 경우로 고려하지 않았고 최단 경로가 1 → v2 → v1 → n 인 경우도 고려하지 않았다. (WA)
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int INTMAX = 10000000;
int n, e, v1, v2;
vector<vector<pair<int, int>>> edge;
int dijkstra(int s, int e) {
vector<int> dst(n + 1, INTMAX);
priority_queue<pair<int, int>> pq;
dst[s] = 0;
pq.emplace(0, s);
while (!pq.empty()) {
int cost = -pq.top().first;
int cur = pq.top().second;
pq.pop();
for (auto nxt: edge[cur]) {
int newcost = cost + nxt.second;
if (newcost < dst[nxt.first]) {
dst[nxt.first] = newcost;
pq.emplace(-newcost, nxt.first);
}
}
}
return dst[e];
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> e;
edge = vector<vector<pair<int, int>>>(n + 1);
for (int i = 0; i < e; i++) {
int a, b, c;
cin >> a >> b >> c;
edge[a].emplace_back(b, c);
edge[b].emplace_back(a, c);
}
cin >> v1 >> v2;
int ans1 = dijkstra(1, v1) + dijkstra(v1, v2) + dijkstra(v2, n);
int ans2 = dijkstra(1, v2) + dijkstra(v2, v1) + dijkstra(v1, n);
if (ans1 >= INTMAX && ans2 >= INTMAX) cout << -1 << '\n';
else cout << min(ans1, ans2) << '\n';
}
이 문제에서 다익스트라 코드 동작 과정은 다음과 같다.
- 초기화: 모든 노드의 최단 경로를 매우 큰 값으로 초기 설정하여 아직 방문되지 않았음을 표시한다.
- 우선순위 큐 사용: 우선순위 큐를 이용해 출발 노드부터 탐색을 시작하며, 거리가 짧은 노드를 먼저 처리하도록 한다. 현재 노드를 큐에서 꺼내어 연결된 인접 노드를 확인한다.
- 거리 업데이트: 현재 노드를 통해 인접 노드로 가는 새로운 경로가 더 짧으면, 최단 경로 정보를 갱신한다. 갱신된 경로는 다시 우선순위 큐에 넣어 다른 경로보다 우선적으로 처리될 수 있도록 한다.
- 최종 경로 계산: 1 → v1 → v2 → n 경로와 1 → v2 → v1 → n 노드 경로의 최단 비용을 각각 계산한다. 두 경로 중 최소값을 최종 경로 비용으로 출력하며, 둘 다 불가능할 경우 -1을 출력한다.
(AC)
'PS' 카테고리의 다른 글
[C++] 알파벳 (백준 1987번) (0) | 2024.11.24 |
---|---|
[C++] 별 찍기 - 11 (백준 2448번) (0) | 2024.11.23 |
[C++] 트리의 지름 (백준 1967번) (0) | 2024.11.19 |
[C++] 숨바꼭질 3 (백준 13549번) (0) | 2024.11.14 |
[C++] 곱셈 (백준 1629번) (2) | 2024.11.13 |
Comments