[Luogu2901][USACO08MAR]牛慢跑Cow Jogging Astar K短路
题目链接:https://daniu.luogu.org/problem/show?pid=2901
Astar的方程$f(n)=g(n)+h(n)$,在这道题中我们可以反向最短路处理出$h(n)$的精确值。然后跑Astar找K次最短路就好了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 int inline readint(){ 7 int Num;char ch; 8 while((ch=getchar())<'0'||ch>'9');Num=ch-'0'; 9 while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0'; 10 return Num; 11 } 12 int N,M,K; 13 int to[10010],ne[10010],w[10010],fir[1010],cnt=0; 14 void add(int a,int b,int c){ 15 to[++cnt]=b; 16 w[cnt]=c; 17 ne[cnt]=fir[a]; 18 fir[a]=cnt; 19 } 20 int nto[10010],nne[10010],nw[10010],nfir[1010],ncnt=0; 21 void nadd(int a,int b,int c){ 22 nto[++ncnt]=b; 23 nw[ncnt]=c; 24 nne[ncnt]=nfir[a]; 25 nfir[a]=ncnt; 26 } 27 int dis[1010]; 28 bool in[1010]; 29 queue <int> q; 30 void Spfa(){ 31 memset(dis,127/3,sizeof(dis)); 32 in[1]=true; 33 dis[1]=0; 34 q.push(1); 35 int u; 36 while(!q.empty()){ 37 int u=q.front(); 38 q.pop(); 39 in[u]=false; 40 for(int i=nfir[u];i!=-1;i=nne[i]){ 41 int v=nto[i]; 42 if(dis[v]>dis[u]+nw[i]){ 43 dis[v]=dis[u]+nw[i]; 44 if(!in[v]){ 45 in[v]=true; 46 q.push(v); 47 } 48 } 49 } 50 } 51 } 52 struct NODE{ 53 int d,num; 54 NODE(int _d=0,int _num=0){ 55 d=_d; 56 num=_num; 57 } 58 bool operator < (const NODE &_)const{ 59 return d>_.d; 60 } 61 }; 62 int ans[110],rk=0; 63 priority_queue <NODE> Q; 64 void Astar(){ 65 Q.push(NODE(dis[N],N)); 66 NODE u; 67 while(!Q.empty()){ 68 u=Q.top(); 69 Q.pop(); 70 if(u.num==1){ 71 ans[++rk]=u.d; 72 if(rk==K) return; 73 } 74 for(int i=fir[u.num];i!=-1;i=ne[i]) 75 Q.push(NODE(u.d-dis[u.num]+w[i]+dis[to[i]],to[i])); 76 } 77 } 78 int main(){ 79 memset(fir,-1,sizeof(fir)); 80 memset(nfir,-1,sizeof(nfir)); 81 N=readint(); 82 M=readint(); 83 K=readint(); 84 for(int i=1;i<=M;i++){ 85 int a=readint(), 86 b=readint(), 87 c=readint(); 88 add(a,b,c); 89 nadd(b,a,c); 90 } 91 Spfa(); 92 Astar(); 93 for(int i=1;i<=K;i++) 94 if(ans[i]) printf("%d\n",ans[i]); 95 else puts("-1"); 96 return 0; 97 }