if(now_cost > dist[now_node]) continue;
를 제거해 주고 각 정점마다 최소 k 번 이상 방문하게 해야 한다. 각 정점이 만약 K 번 방문하지 못한다면 K 번째 간선은 없다.해결 전략에서 말한것과 같이 그대로 구현하면 된다.
각 정점마다 K 번 이상 방문하게 한다.
priority_queue<int, vector<int>, less<int>> city[1001];
if(city[next_node].size() < k) {
city[next_node].push(next_cost);
pq.push({next_cost, next_node});
}
else {
if(city[next_node].top() > next_cost) {
city[next_node].pop();
city[next_node].push(next_cost);
pq.push({next_cost, next_node});
}
}
정점의 최대 개수 (V) : 1000 (1천)
간선의 최대 개수 (E) : 2000000 (2백만)
도시의 최대 개수 (K): 100 (1백)
일반적인 다익스트라의 시간복잡도는 O(ElogE)다. 그래서 k개의 도시를 도니깐 O(k * ElogE)일까? 이 문제는 일반적인 다익스트라의 코드를 변경 했으므로 시간복잡도에 주의하자.
오히려 if(now_cost > dist[now_node]) continue;
부분을 제거해서 최악의 경우 O(E^2 / 2)인데? 그럼 O(2백만^2 / 2) 무려 1조다.
근데 잘 생각해보자 우리는 각 정점에 연결되는 간선들의 소요시간이 오름차순으로 정렬되어 있기때문에 한 정점에서 다른 정점을 가는데 걸리는 최대 소요시간은 1000시간
이다. 그럼 최악의 경우에 한 정점에서 다른 정점으로 가는데 간선이 2백만개씩 있더라도 1000개의 간선만 거치면 최소 소요시간을 알 수 있다.
그래서 시간복잡도는 O(V * 1000 * K)
다.
최악의 경우 1000 * 1000 * 100 으로 O(1억)
이다.
#include <bits/stdc++.h>
#define INF 1e9
using namespace std;
int V, E, k, start = 1;
vector<pair<int, int> > graph[1001];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
priority_queue<int, vector<int>, less<int>> city[1001];
void input() {
cin >> V >> E >> k; // n, m, k
int u, v, w;
for(int i=0; i<E; i++) {
cin >> u >> v >> w;
graph[u].push_back({w, v});
}
}
void dijkstra() {
pq.push({0, start});
city[start].push(0);
while(!pq.empty()) {
int now_cost = pq.top().first;
int now_node = pq.top().second;
pq.pop();
for(int i=0; i<graph[now_node].size(); i++) {
int next_cost = now_cost + graph[now_node][i].first;
int next_node = graph[now_node][i].second;
if(city[next_node].size() < k) {
city[next_node].push(next_cost);
pq.push({next_cost, next_node});
} else {
if(city[next_node].top() > next_cost) {
city[next_node].pop();
city[next_node].push(next_cost);
pq.push({next_cost, next_node});
}
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
input();
dijkstra();
// output
for(int i=1; i<=V; i++) {
if(city[i].size() < k) cout << -1 << endl;
else {
cout << city[i].top() << endl;
}
}
return 0;
}