득이공간

[백준 C++] 1504 특정한 최단 경로 - 다익스트라 본문

PS/알고리즘 문제풀이

[백준 C++] 1504 특정한 최단 경로 - 다익스트라

쟁득 2024. 3. 5. 10:28
 

1504번: 특정한 최단 경로

첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존

www.acmicpc.net

cpp
#include <iostream> #include <climits> #include <list> #include <queue> using namespace std; const int Infinite = INT_MAX; typedef pair<int, int> node; int N, E; list<pair<int, int>> Neighbors[801]; int Distance[801]; priority_queue<node, vector<node>, greater<node>> SQ; int Dijkstra(int Start, int End) { for (int i = 1; i <= N; ++i) { ‌‌Distance[i] = Infinite; } ‌Distance[Start] = 0; ‌SQ.emplace(0, Start); while (!SQ.empty()) { ‌‌int CurIdx = SQ.top().second; ‌‌int CurCst = SQ.top().first; ‌‌SQ.pop(); ‌‌if (CurCst > Distance[CurIdx]) ‌‌{ ‌‌‌continue; ‌‌} ‌‌for (const pair<int, int>& N : Neighbors[CurIdx]) ‌‌{ ‌‌‌int NewCst = Distance[CurIdx] + N.second; ‌‌‌if (NewCst < Distance[N.first]) ‌‌‌{ ‌‌‌‌Distance[N.first] = NewCst; ‌‌‌‌SQ.emplace(NewCst, N.first); ‌‌‌} ‌‌} } return Distance[End]; } int main() { ‌ios::sync_with_stdio(false); ‌cin.tie(nullptr); cout.tie(nullptr); ‌cin >> N >> E; for (int i = 0; i < E; ++i) { ‌‌int A, B, C; ‌‌cin >> A >> B >> C; ‌‌Neighbors[A].emplace_back(B, C); ‌‌Neighbors[B].emplace_back(A, C); } int X, Y; ‌cin >> X >> Y; int SolA = Infinite, SolB = Infinite; int Dst1, Dst2, Dst3; ‌Dst1 = Dijkstra(1, X); ‌Dst2 = Dijkstra(X, Y); ‌Dst3 = Dijkstra(Y, N); if (Dst1 != Infinite && Dst2 != Infinite && Dst3 != Infinite) { ‌‌SolA = Dst1 + Dst2 + Dst3; } ‌Dst1 = Dijkstra(1, Y); ‌Dst2 = Dijkstra(Y, X); ‌Dst3 = Dijkstra(X, N); if (Dst1 != Infinite && Dst2 != Infinite && Dst3 != Infinite) { ‌‌SolB = Dst1 + Dst2 + Dst3; } if (SolA == Infinite && SolB == Infinite) { ‌‌cout << -1; ‌‌return 0; } ‌cout << min(SolA, SolB); }

 

다익스트라 알고리즘 구현과 경유지의 경유 순서에 따라 최소값이 달라지는 점을 캐치하는 것이 중요한 문제입니다.

 

일반적인 다익스트라 알고리즘 풀이 과정입니다.

1. 인접 리스트로 그래프 구현

2. 최단 거리 배열 초기화 - 출발 노드가 0, 나머지는 무한

3. 최단 거리 배열에서 값이 가장 작은 노드 선택 - 우선순위큐 사용

4. 해당 노드의 인접 노드들의 최단 거리값 업데이트 - min(해당노드 최단거리값+가중치, 인접노드 최단거리값)

 

알고리즘 구현 후, 문제에서 제시한 두 경유지 중 먼저 방문할 경유지를 선택해서

각 경우 마다 최소경로를 모두 구하고 그 중 더 작은 값을 선택하면 됩니다.