【USACO Mar08】 奶牛跑步 A-star k短路

时间:2022-01-27 08:01:59

Description

Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚.

Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M(1<=M<=10,000)条路,每条路连接两个用1..N(1<=N<=1000)标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是Bessie的牛棚;地点1是池塘.

很快, Bessie厌倦了一直走同一条路.所以她想走不同的路,更明确地讲,她想找出K(1<=K<=100)条不同的路经.为了避免过度劳累,她想使这K条路径为最短的K条路径.

请帮助Bessie找出这K条最短路经的长度.你的程序需要读入农场的地图, 一些从Xi到Yi的路径和它们的长度(Xi,Yi,Di).
所有(Xi,Yi,Di) 满足( 1<=Yi<Xi; Yi<Xi<=N, 1<=Di<=1,000,000 ).

Input

第1行: 3个数: N,M,K
第2..M+1行: 第 i+1行包含3个数 Xi,Yi,Di, 表示一条下坡的路.

Output

第1..K行: 第i行包含第i最短路径的长度,或−1如果这样的路径不存在.如果多条路径有同样的长度,请注意将这些长度逐一列出.

Sample Input

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

Sample Output

1
2
2
3
6
7
-1

Hint

【样例解释】
路径分别为(5−1),(5−3−1),(5−2−1),(5−3−2−1),(5−4−3−1),(5−4−3−2−1)

题解:

裸k短路,估价函数定的是到起点的距离+到终点最短路之和

 #include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
const int N=,M=;
int gi(){
int str=;char ch=getchar();
while(ch>'' || ch<'')ch=getchar();
while(ch>='' && ch<='')str=(str<<)+(str<<)+ch-,ch=getchar();
return str;
}
int n,m,k,head[N],num=,Head[N],NUM=;
struct Lin{
int next,to,dis;
}a[M<<],b[M<<];
void init2(int x,int y,int dis){
b[++NUM].next=Head[x];
b[NUM].to=y;
b[NUM].dis=dis;
Head[x]=NUM;
}
void init(int x,int y,int dis){
a[++num].next=head[x];
a[num].to=y;
a[num].dis=dis;
head[x]=num;
}
int f[N],qq[N*],mod=N*;bool vis[N];
void spfa()
{
int t=,sum=,x,u;
qq[]=;vis[]=true;
memset(f,/,sizeof(f));
f[]=;
while(t!=sum)
{
t++;t%=mod;
x=qq[t];
for(int i=Head[x];i;i=b[i].next){
u=b[i].to;
if(f[x]+a[i].dis<f[u]){
f[u]=f[x]+a[i].dis;
if(!vis[u])vis[u]=true,sum++,sum%=mod,qq[sum]=u;
}
}
vis[x]=false;
}
}
struct node{
int x,dis,val;
bool operator<(const node &p)const{
return val>p.val;
}
};
priority_queue<node>q;
int cnt=;
void Astar()
{
q.push((node){n,,f[n]});
int u;node p;
while(!q.empty())
{
p=q.top();q.pop();
if(p.x==)
{
if(cnt<=k)
printf("%d\n",p.dis),cnt++;
if(cnt==k+)return ;
}
for(int i=head[p.x];i;i=a[i].next)
{
u=a[i].to;
q.push((node){u,p.dis+a[i].dis,p.dis+a[i].dis+f[u]});
}
}
}
int main()
{
n=gi();m=gi();k=gi();
int x,y,z;
for(int i=;i<=m;i++){
x=gi();y=gi();z=gi();
init(x,y,z);init2(y,x,z);
}
spfa();
Astar();
while(cnt<=k)printf("-1\n"),cnt++;
return ;
}