[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 }

 

posted @ 2017-09-20 21:54  halfrot  阅读(204)  评论(0编辑  收藏  举报