题目描述
贝西终于尝到了懒惰的后果,决定每周从谷仓到池塘慢跑几次来健身。当然,她不想跑得太累,所以她只打算从谷仓慢跑下山到池塘,然后悠闲地散步回谷仓。
同时,贝西不想跑得太远,所以她只想沿着通向池塘的最短路径跑步。一共有 �M 条道路,其中每一条都连接了两个牧场。这些牧场从 11 到 �N 编号,如果 �>�X>Y,则说明牧场 �X 的地势高于牧场 �Y,即下坡的道路是从 �X 通向 �Y 的,�N 为贝西所在的牛棚(最高点),11 为池塘(最低点)。
然而,一周之后,贝西开始对单调的路线感到厌烦,她希望可以跑不同的路线。比如说,她希望能有 �K 种不同的路线。同时,为了避免跑得太累,她希望这 �K 条路线是从牛棚到池塘的路线中最短的 �K 条。如果两条路线包含的道路组成的序列不同,则这两条路线被认为是不同的。
请帮助贝西算算她的训练强度,即将牧场网络里最短的 �K 条路径的长度分别算出来。你将会被提供一份牧场间路线的列表,每条道路用 (��,��,��)(Xi,Yi,Di) 表示,意为从 ��Xi 到 ��Yi 有一条长度为 ��Di 的下坡道路。
输入格式
第一行三个用空格分开的整数 �,�,�N,M,K,其中 。
第二行到第 �+1M+1 行每行有三个用空格分开的整数 ��,��,��Xi,Yi,Di,描述一条下坡的道路。
输出格式
共 �K 行,在第 �i 行输出第 �i 短的路线长度,如果不存在则输出 −1−1。如果出现多种有相同长度的路线,务必将其全部输出。
样例
输入数据#1
5 8 7
5 4 1
5 3 1
5 2 1
5 1 1
4 3 4
3 1 1
3 2 1
2 1 1
输出数据#1
1
2
2
3
6
7
-1
解释#1
这些路线分别为 (5-1)、(5-3-1)、(5-2-1)、(5-3-2-1)、(5-4-3-1) 和 (5-4-3-2-1)。
数据范围
- 对于全部的测试点,保证 1≤�≤1,0001≤N≤1,000,1≤�≤1×1041≤M≤1×104,1≤�≤1001≤K≤100,1≤��<��≤�1≤Yi<Xi≤N,1≤��≤1×1061≤Di≤1×106,
- https://www.topscoding.com/p/1081
https://www.topscoding.com/p/1081
AC代码:
-
#include<bits/stdc++.h> using namespace std; struct edge { int v, w, next; } e[100010], e1[100010]; int head[1010], head1[1010], cnt; int n, m, k; int dis[1010]; bool vis[1010]; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();} while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();} return x * f; } void insert(int u, int v, int w) { e[++cnt].v = v, e[cnt].w = w, e[cnt].next = head[u], head[u] = cnt; e1[cnt].v = u, e1[cnt].w = w, e1[cnt].next = head1[u], head1[u] = cnt; //反向建图 } void spfa() { memset(dis, 1e9, sizeof dis); queue<int> q; dis[n] = 0; vis[n] = 1; q.push(n); int u; while (!q.empty()) { u = q.front(); q.pop(); vis[u] = false; for (int i = head1[u]; i; i = e1[i].next) { int v = e1[i].v, w = e1[i].w; if (dis[v] > dis[u] + w) { dis[v] = dis[u] + w; if (!vis[v]) { vis[v] = true; q.push(v); } } } } } struct node { int d, id; node () {} node (int dd, int di) { d = dd; id = di; } bool operator < (const node & x) const { return x.d < d; } }; int ans[110], kk; priority_queue<node> q; void A_star() { q.push(node(dis[n], n)); while (!q.empty()) { int d = q.top().d, num = q.top().id; q.pop(); if (num == 1) { ans[++kk] = d; if (kk == k) return; } for (int i = head[num]; i; i = e[i].next) { q.push(node(d - dis[num] + e[i].w + dis[e[i].v], e[i].v)); } } } int main() { n = read(), m = read(), k = read(); for (int i = 1; i <= m; i++) { int u = read(), v = read(), w = read(); insert(u, v, w); } spfa(); A_star(); for (int i = 1; i <= k; i++) { if (ans[i]) printf("%d\n", ans[i]); else puts("-1"); } return 0; }