bzoj1598
K短路
和超级钢琴之类的差不多
先反图跑最短路,从原点向外拓展,每个点最多拓展k次,否则不可能是k短路
#include<bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int N = 1e4 + 5, inf = 0x3f3f3f3f; int rd() { int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x * f; } int n, m, k, cnt = 1; int h[N], d[N], vis[N], ans[N]; struct edge { int nxt, to, w; } e[N << 1]; void link(int u, int v, int w) { e[++cnt].nxt = h[u]; h[u] = cnt; e[cnt].to = v; e[cnt].w = w; } namespace I { int cnt = 1; int h[N]; struct edge { int nxt, to, w; } e[N << 1]; void link(int u, int v, int w) { e[++cnt].nxt = h[u]; h[u] = cnt; e[cnt].to = v; e[cnt].w = w; } void dij(int s, int *d) { priority_queue<pii, vector<pii>, greater<pii> > q; for(int i = 1; i <= n; ++i) d[i] = inf; d[s] = 0; q.push(make_pair(0, s)); while(!q.empty()) { pii o = q.top(); q.pop(); int u = o.second; if(d[u] < o.first) continue; for(int i = h[u]; i; i = e[i].nxt) if(d[e[i].to] > d[u] + e[i].w) { d[e[i].to] = d[u] + e[i].w; q.push(make_pair(d[e[i].to], e[i].to)); } } } } int main() { n = rd(); m = rd(); k = rd(); for(int i = 1; i <= m; ++i) { int u = rd(), v = rd(), w = rd(); I :: link(v, u, w); link(u, v, w); } I :: dij(1, d); priority_queue<pii, vector<pii>, greater<pii> > q; q.push(make_pair(d[n], n)); memset(ans, -1, sizeof(ans)); while(!q.empty()) { int u = q.top().second, dis = q.top().first; q.pop(); ++vis[u]; if(u == 1) { ans[vis[u]] = dis; if(vis[u] == k) break; } if(vis[u] <= k) for(int i = h[u]; i; i = e[i].nxt) q.push(make_pair(dis - d[u] + d[e[i].to] + e[i].w, e[i].to)); } for(int i = 1; i <= k; ++i) printf("%d\n", ans[i]); return 0; }