이 문제는 특이하게 최단경로를 구하는 문제가 아니라 K번째 최단경로를 구하는 문제이다.
2번째 최단경로라는 말은 2번째로 빠른 경로를 의미한다.
최단거리를 구하는 알고리즘은 다익스트라 알고리즘으로 구현할 수 있는데 K번째 최단경로는 어떻게 구할까??
우선 나는 이 문제를 다익스트라 알고리즘을 살짝 변형해서 해결하였다.
다익스트라 알고리즘은 원래 선택된 노드와 이웃한 노드의 거리의 합이 저장되어 있는 값보다 작으면 값을 갱신하고 큐에 노드를 넣어줬었는데 나는 이 부분을 제거했다.
그냥 갱신은 모르겠고 전부다 큐에 집어넣었다. 그러고 노드마다 방문된 횟수를 저장하고 만약 K번째로 노드가 방문되었다면 그 값을 배열에 저장하였다.
어차피 우선순위 큐를 사용하기 때문에 작은게 우선으로 뽑히고 만약 노드가 K번 방문되었다면 그게 답이 되기 때문.
#include <iostream>
#include <vector>
#include <queue>
#define INF 987654321;
using namespace std;
vector<pair<int, int>>v[1001];
int visited[1001];
int arr[1001];
priority_queue<pair<int, int>>pq;
int main(void)
{
int n, m, k = 0;
cin >> n >> m >> k;
for (int i = 0; i < m; i++)
{
int a, b, c = 0;
cin >> a >> b >> c;
v[a].push_back({ b,c });
}
for (int i = 1; i <= n; i++)
{
arr[i] = INF;
}
pq.push({ 0,1 });
while (!pq.empty())
{
int distance = -pq.top().first;
int cur = pq.top().second;
pq.pop();
visited[cur]++;
if (visited[cur] == k)
{
arr[cur] = distance;
}
else if (visited[cur] > k)
{
continue;
}
for (int i = 0; i < v[cur].size(); i++)
{
int next = v[cur][i].first;
int nextdistance = distance + v[cur][i].second;
pq.push({ -nextdistance ,next });
}
}
for (int i = 1; i <= n; i++)
{
if (arr[i] != 987654321)
{
cout << arr[i] << '\n';
}
else
{
cout << -1 << '\n';
}
}
return 0;
}
'백준 > 코테문제집' 카테고리의 다른 글
백준 풀면서 느낀점. (0) | 2025.04.30 |
---|---|
[백준] C++ 최단 경로 구하기(1753) (0) | 2025.02.28 |
[백준] C++ 거짓말(1043) (0) | 2025.02.26 |
[백준] C++ 집합의 표현(1717) (0) | 2025.02.17 |
[백준] C++ 나머지 합(10986) (0) | 2025.01.23 |