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 }
View Code

手动队列

技术分享图片
  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 }
View Code

例题2:

POJ2449

裸的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 }
View Code

 

以上是关于A*求第k短路的主要内容,如果未能解决你的问题,请参考以下文章

[算法学习]A*求第k短路

A* 算法求第 K 短路

ACM模板~求第k短路 ~~~A*+Dijkstra

2019 CCPC - 网络选拔赛 D path(求第k短路)

poj 2449 Remmarguts' Date 求第k短路 Astar算法

POJ2449 第k短路/A*