A* algorithm study notes

Basic principle of A* algorithm

The A-star algorithm is the most effective direct search method for solving the shortest path in a static road network, and it is also an effective algorithm for solving many search problems. The closer the estimated distance value in the algorithm is to the actual value, the faster the final search speed.

F[i]=G[i]+H[i];

This is the core expression of the A* algorithm, that is, the current cost + the state with the smallest future estimate is taken out each time . The estimated value H[i] <= actual future cost .

If the estimated value is greater than the actual future cost, the correctness of the A* algorithm cannot be guaranteed. (I read the counterexample of "Advanced Guide to Algorithm Competition" and didn't understand it. I will add it later if I understand it).

K short circuit

#include<bits/stdc++.h>
using namespace std;
#define fp(i,a,b) for(register int i=a;i<=b;i++)
#define fb(i,a,b) for(register int i=a;i>=b;i--)
#define sc(a) scanf("%d",&a)
#define scf(a,b) scanf("%d%d",&a,&b)
const int MAXN=1e5+5;
struct Node{
	int f,g,h;
	bool operator<(const Node &a)const{
	    if(a.f==f) return a.g<g;
	    return a.f<f;
	}
};
struct Edge{
	int to,w,prev;
}edge1[MAXN<<1],edge2[MAXN<<1];
int n,m,s,t,k,cnt1,cnt2,ans,head1[MAXN],head2[MAXN],dis[MAXN],vis[MAXN];
inline void add(int x,int y,int w){
	edge1[++cnt1].to=y;
	edge1[cnt1].w=w;
	edge1[cnt1].prev=head1[x];
	head1[x]=cnt1;
	edge2[++cnt2].to=x;
	edge2[cnt2].w=w;
	edge2[cnt2].prev=head2[y];
	head2[y]=cnt2;
}
inline void spfa(int st){
	queue<int> q;
	memset(dis,0x3f3f3f3f,sizeof(dis));
	q.push(st);vis[st]=1;dis[st]=0;
	while(!q.empty()){
		int x=q.front();q.pop();vis[x]=0;
		for(int i=head2[x];i;i=edge2[i].prev){
			int to=edge2[i].to;
			if(dis[to]>dis[x]+edge2[i].w){
				dis[to]=dis[x]+edge2[i].w;
				if(!vis[to]){
					vis[to]=1;
					q.push(to);
				}
			}
		}
	}
}
inline int Astar(int st,int ed){
	priority_queue<Node> q;
	if(st==ed) k++;
	if(dis[st]==0x3f3f3f3f) return -1;
	struct Node t,tt;
	t.g=0;t.h=st;t.f=t.g+dis[t.h];
	q.push(t);
	while(!q.empty()){
		tt=q.top();q.pop();
		if(tt.h==ed){
			ans++;
			if(ans==k) return tt.g;
		}
		for(int i=head1[tt.h];i;i=edge1[i].prev){
			int to=edge1[i].to;
			t.g=tt.g+edge1[i].w;
			t.h=to;
			t.f=t.g+dis[to];
			q.push(t);
		}
	}
	return -1;
}
int main(){
	scf(n,m);
	fp(i,1,m){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
	}
	scanf("%d%d%d",&s,&t,&k);
	spfa(t);
	printf("%d\n",Astar(s,t));
	return 0;
}
/*
4 5
1 2 2
2 3 3
1 3 5
2 4 1
4 3 3
1 3 3
*/

The most important part of the A-star algorithm is to find a suitable valuation function. The valuation function of this classic A-star template problem is the shortest path from the end point to each point. So you need to reverse the map once and run the shortest path again. If the end point only needs to appear k times, then its current cost is the kth short circuit. Because every time the elements taken out of the priority queue are the optimal solutions under the current conditions . This question also needs to judge the coincidence of the starting point and the ending point.

Guess you like

Origin blog.csdn.net/weixin_43916777/article/details/104224307