USACO2008mar-gold牛跑步(第k短路:A-star)
描述
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条最短路经的长度.你的程序需要读入农场的地图, 一些从到的路经和它们的长度. 所有(X_i, Y_i, D_i)满足(1 <= Y_i < X_i; Y_i < X_i <= N, 1 <= D_i <= 1,000,000).
输入
第1行: 3个数: N, M, 和K
第 2…M+1行: 第 i+1 行包含3个数 X_i, Y_i, 和 D_i, 表示一条下坡的路.
输出
第1…K行: 第i行包含第i最短路经的长度,或-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
2
2
3
6
7
-1
提示
输出解释:
路经分别为(5-1), (5-3-1), (5-2-1), (5-3-2-1), (5-4-3-1), (5-4-3-2-1).
第k短路裸题。。。。
所以说A*还是不会啊。。。。。
大概就那样吧。。。反正就是搜到第k次就那啥。。。。。乱胡一发、、、
赶紧溜。。。。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int inf=200000000;
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
const int N=1005;
const int M=20005;
int n,m,adj[N],nxt[M],to[M],val[M],k,dis[N],ans[106],tim,head[N],len[M],nec[M],go[M],cnt,tot;
bool vis[N];
inline void addedge(int u,int v,int w){
nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,len[cnt]=w;
nec[++tot]=head[v],head[v]=tot,go[tot]=u,val[tot]=w;
}
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
inline void dijkstra(){
for(int i=1;i<=n;i++)dis[i]=inf;
dis[1]=0,vis[1]=0;q.push(make_pair(0,1));
while(!q.empty()){
int u=q.top().second;q.pop();
if(vis[u])continue;vis[u]=true;
for(int e=head[u];e;e=nec[e]){
int v=go[e];
if(dis[u]+len[e]<dis[v]){
dis[v]=dis[u]+len[e],q.push(make_pair(dis[v],v));
}
}
}
}
inline void a_star(){
if(dis[n]==inf)return;
q.push(make_pair(dis[n],n));
while(!q.empty()){
int u=q.top().second,w=q.top().first;q.pop();
if(u==1)ans[++tim]=w;
if(tim==k)break;
int v=w-dis[u];
for(int e=adj[u];e;e=nxt[e]){
q.push(make_pair(v+val[e]+dis[to[e]],to[e]));
}
}
}
int main(){
n=read(),m=read(),k=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
addedge(u,v,w);
}
dijkstra();
a_star();
for(int i=1;i<=k;i++){
if(ans[i])cout<<ans[i]<<'\n';
else cout<<"-1"<<'\n';
}
}