A*求第k短路
Posted ehanla
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A*求第k短路相关的知识,希望对你有一定的参考价值。
A*算法
理论:https://www.cnblogs.com/n-u-l-l/archive/2012/07/29/2614194.html
例题1:
UESTC
A*+最短路
1 //A* 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 9 const int N=2e3+10; 10 const int M=2e5+10; 11 const int INF=0x3f3f3f3f; 12 13 bool vis[N]; 14 int head1[N],head2[N],d[N],q[5*M]; 15 int cnt,k; 16 17 struct Edge{ 18 int to,next,w; 19 }e1[M],e2[M]; 20 21 struct node{ 22 int f,g,v; 23 node(int F,int G,int V):f(F),g(G),v(V){} 24 node(){} 25 friend bool operator < (node p1,node p2){ 26 if(p1.f==p2.f) return p1.g>p2.g; 27 return p1.f>p2.f; 28 } 29 }; 30 31 void add(int u,int v,int w){ 32 e1[cnt].w=w;e1[cnt].to=u;e1[cnt].next=head1[v];head1[v]=cnt; 33 e2[cnt].w=w;e2[cnt].to=v;e2[cnt].next=head2[u];head2[u]=cnt++; 34 } 35 36 void SPFA(int st){ 37 queue <int> Q; 38 vis[st]=true; 39 d[st]=0; 40 Q.push(st); 41 while(!Q.empty()){ 42 int u=Q.front(); 43 Q.pop(); 44 vis[u]=false; 45 for(int i=head1[u];~i;i=e1[i].next){ 46 int v=e1[i].to,w=e1[i].w; 47 if(d[v]>d[u]+w){ 48 d[v]=d[u]+w; 49 if(!vis[v]){ 50 vis[v]=true; 51 Q.push(v); 52 } 53 } 54 } 55 } 56 } 57 58 int A_star(int st,int en){ 59 node cur; 60 int cnt=0; 61 if(st==en) k++; 62 if(d[st]==INF) return -1; 63 priority_queue <node> Q; 64 Q.push(node(d[st],0,st)); 65 while(!Q.empty()){ 66 cur=Q.top(); 67 int nv=cur.v; 68 Q.pop(); 69 if(nv==en){ 70 cnt++; 71 if(cnt==k) return cur.g; 72 } 73 for(int i=head2[cur.v];~i;i=e2[i].next){ 74 Q.push(node(cur.g+e2[i].w+d[e2[i].to],cur.g+e2[i].w,e2[i].to)); 75 } 76 } 77 return -1; 78 } 79 80 void init(){ 81 cnt=0; 82 memset(d,0x3f,sizeof(d)); 83 memset(vis,false,sizeof(vis)); 84 memset(head1,-1,sizeof(head1)); 85 memset(head2,-1,sizeof(head2)); 86 } 87 88 int main(){ 89 int n,m,st,en; 90 scanf("%d%d%d",&n,&m,&k); 91 scanf("%d%d",&st,&en); 92 init(); 93 for(int i=1;i<=m;i++){ 94 int a,b,c; 95 scanf("%d%d%d",&a,&b,&c); 96 add(a,b,c); 97 } 98 SPFA(en); 99 printf("%d ",A_star(st,en)); 100 return 0; 101 }
手动队列
1 //A* 手动队列 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 9 const int N=2e3+10; 10 const int M=2e5+10; 11 const int INF=0x3f3f3f3f; 12 13 bool vis[N]; 14 int head1[N],head2[N],d[N],q[5*M]; 15 int cnt,k; 16 17 struct Edge{ 18 int to,next,w; 19 }e1[M],e2[M]; 20 21 struct node{ 22 int f,g,v; 23 node(int F,int G,int V):f(F),g(G),v(V){} 24 node(){} 25 friend bool operator < (node p1,node p2){ 26 if(p1.f==p2.f) return p1.g>p2.g; 27 return p1.f>p2.f; 28 } 29 }; 30 31 void add(int u,int v,int w){ 32 e1[cnt].w=w;e1[cnt].to=u;e1[cnt].next=head1[v];head1[v]=cnt; 33 e2[cnt].w=w;e2[cnt].to=v;e2[cnt].next=head2[u];head2[u]=cnt++; 34 } 35 36 void SPFA(int st){ 37 int h=0,t=1; 38 vis[st]=true; 39 d[st]=0; 40 q[0]=st; 41 while(h<t){ 42 int u=q[h++]; 43 vis[u]=false; 44 for(int i=head1[u];~i;i=e1[i].next){ 45 int v=e1[i].to,w=e1[i].w; 46 if(d[v]>d[u]+w){ 47 d[v]=d[u]+w; 48 if(!vis[v]){ 49 vis[v]=true; 50 q[t++]=v; 51 } 52 } 53 } 54 } 55 } 56 57 int A_star(int st,int en){ 58 node cur; 59 int cnt=0; 60 if(st==en) k++; 61 if(d[st]==INF) return -1; 62 priority_queue <node> Q; 63 Q.push(node(d[st],0,st)); 64 while(!Q.empty()){ 65 cur=Q.top(); 66 int nv=cur.v; 67 Q.pop(); 68 if(nv==en){ 69 cnt++; 70 if(cnt==k) return cur.g; 71 } 72 for(int i=head2[cur.v];~i;i=e2[i].next){ 73 Q.push(node(cur.g+e2[i].w+d[e2[i].to],cur.g+e2[i].w,e2[i].to)); 74 } 75 } 76 return -1; 77 } 78 79 void init(){ 80 cnt=0; 81 memset(d,0x3f,sizeof(d)); 82 memset(vis,false,sizeof(vis)); 83 memset(head1,-1,sizeof(head1)); 84 memset(head2,-1,sizeof(head2)); 85 } 86 87 int main(){ 88 int n,m,st,en; 89 scanf("%d%d%d",&n,&m,&k); 90 scanf("%d%d",&st,&en); 91 init(); 92 for(int i=1;i<=m;i++){ 93 int a,b,c; 94 scanf("%d%d%d",&a,&b,&c); 95 add(a,b,c); 96 } 97 SPFA(en); 98 printf("%d ",A_star(st,en)); 99 return 0; 100 }
例题2:
裸的A*+最短路。
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 const int N=2e3+10; 9 const int M=2e5+10; 10 const int INF=0x3f3f3f3f; 11 12 bool vis[N]; 13 int head1[N],head2[N],d[N],q[5*M]; 14 int cnt,k; 15 16 struct Edge{ 17 int to,next,w; 18 }e1[M],e2[M]; 19 20 struct node{ 21 int f,g,v; 22 node(int F,int G,int V):f(F),g(G),v(V){} 23 node(){} 24 friend bool operator < (node p1,node p2){ 25 if(p1.f==p2.f) return p1.g>p2.g; 26 return p1.f>p2.f; 27 } 28 }; 29 30 void add(int u,int v,int w){ 31 e1[cnt].w=w;e1[cnt].to=u;e1[cnt].next=head1[v];head1[v]=cnt; 32 e2[cnt].w=w;e2[cnt].to=v;e2[cnt].next=head2[u];head2[u]=cnt++; 33 } 34 35 void SPFA(int st){ 36 queue <int> Q; 37 vis[st]=true; 38 d[st]=0; 39 Q.push(st); 40 while(!Q.empty()){ 41 int u=Q.front(); 42 Q.pop(); 43 vis[u]=false; 44 for(int i=head1[u];~i;i=e1[i].next){ 45 int v=e1[i].to,w=e1[i].w; 46 if(d[v]>d[u]+w){ 47 d[v]=d[u]+w; 48 if(!vis[v]){ 49 vis[v]=true; 50 Q.push(v); 51 } 52 } 53 } 54 } 55 } 56 57 int A_star(int st,int en){ 58 node cur; 59 int cnt=0; 60 if(st==en) k++; 61 if(d[st]==INF) return -1; 62 priority_queue <node> Q; 63 Q.push(node(d[st],0,st)); 64 while(!Q.empty()){ 65 cur=Q.top(); 66 int nv=cur.v; 67 Q.pop(); 68 if(nv==en){ 69 cnt++; 70 if(cnt==k) return cur.g; 71 } 72 for(int i=head2[cur.v];~i;i=e2[i].next){ 73 Q.push(node(cur.g+e2[i].w+d[e2[i].to],cur.g+e2[i].w,e2[i].to)); 74 } 75 } 76 return -1; 77 } 78 79 void init(){ 80 cnt=0; 81 memset(d,0x3f,sizeof(d)); 82 memset(vis,false,sizeof(vis)); 83 memset(head1,-1,sizeof(head1)); 84 memset(head2,-1,sizeof(head2)); 85 } 86 87 int main(){ 88 int n,m,st,en; 89 while(scanf("%d%d",&n,&m)!=EOF){ 90 init(); 91 for(int i=1;i<=m;i++){ 92 int a,b,c; 93 scanf("%d%d%d",&a,&b,&c); 94 add(a,b,c); 95 } 96 scanf("%d%d%d",&st,&en,&k); 97 SPFA(en); 98 printf("%d ",A_star(st,en)); 99 } 100 return 0; 101 }
以上是关于A*求第k短路的主要内容,如果未能解决你的问题,请参考以下文章
2019 CCPC - 网络选拔赛 D path(求第k短路)