-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkshortestpaths.cpp
More file actions
75 lines (65 loc) · 1.53 KB
/
Copy pathkshortestpaths.cpp
File metadata and controls
75 lines (65 loc) · 1.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define pii pair<int, int>
#define endl '\n'
#define vi vector<int>
#define vvi vector<vi>
#define pii pair<int, int>
#define vpii vector<pii>
typedef long long ll;
typedef long double ld;
using namespace std;
template<class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
/*
Finds the lengths of the k shortest paths
from 1 to n.
Complexity:
O(k * n * log(k * n))
Source:
https://en.wikipedia.org/wiki/K_shortest_path_routing
Solution to:
https://cses.fi/problemset/task/1196
Algorithm paraphrased:
Keep track of count[u], which is the number of paths
from source to u found. These paths are the shortest
length paths. Keep paths in a heap, pull out the path
with the shortest length, and add edges incrementally.
*/
const int N = 1e5 + 10;
vpii g[N];
int cnt[N];
vector<ll> lengths;
int n, m, k;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m >> k;
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
g[a].pb({b, c});
}
// {cost, endpoint}
multiset<pair<ll, int>> B;
B.insert({0, 1});
while (B.size() && cnt[n] < k) {
auto [cost, endpt] = *B.begin();
B.erase(B.begin());
cnt[endpt]++;
if (endpt == n) {
lengths.pb(cost);
}
if (cnt[endpt] <= k) {
for (auto [y, wei] : g[endpt]) {
B.insert({cost + wei, y});
}
}
}
for (auto len : lengths) {
cout << len << " ";
}
cout << endl;
return 0;
}