1. 程式人生 > >A*求第k短路

A*求第k短路

display ++ truct OS print LG algo IV AD

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\n",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\n",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\n",A_star(st,en));
 99     }
100     return 0;
101 }
View Code

A*求第k短路