网上很多的解析很详细(但我现在只是需要一个简单的板子,因为主要重心不在这里而是图论其他的简单部分的熟练应用。等到以后我会扩充。
A
∗
A*
A∗的核心在于估价函数,预估以后最应该走的路。
所以我们实现求出每个点到终点的距离,每次
b
f
s
bfs
bfs扩充,扩充的过程中不断增加路径长度,同时以
f
[
n
o
d
e
]
=
c
o
s
t
+
d
[
n
o
d
e
.
t
o
]
f[node]=cost+d[node.to]
f[node]=cost+d[node.to]来进行排序。
这样子每次都按照预估最近的一条路走,走过终点第
k
k
k次的时候即是答案。
模板(暑假集训可能用到:请勿照搬)
int n,m,k;
vector<pair<ll,int> >G[maxn];
struct Edge{
int from,to;ll dist;
Edge(){}
Edge(int _from,int _to,ll _dist):from(_from),to(_to),dist(_dist){}
};
Edge ed[maxm];int he[maxn],ne[maxm],etop=1;
void insert(int u,int v,ll w){ed[etop]=Edge(u,v,w);ne[etop]=he[u];he[u]=etop++;}
ll d[maxn];
bool vis[maxn];
struct node{
int to;ll cost;
friend bool operator < (node a,node b){
return a.cost+d[a.to] > b.cost+d[b.to];//估价=当前+到终点最短
}
};
priority_queue<pair<ll, int>, vector<pair<ll, int> >, greater<pair<ll, int> > > q;
void dijkstra(int s){
memset(vis,0,sizeof(vis));
memset(d, 0x3f, sizeof(d));
d[s] = 0;
q.push(make_pair(0, s));
while(!q.empty()){
int now = q.top().second;
q.pop();
if(!vis[now]){
vis[now] = true;
for(int i = he[now]; i; i = ne[i]){
Edge& e = ed[i];
if(d[e.to] > d[now] + e.dist){
d[e.to] = d[now] + e.dist;
q.push(make_pair(d[e.to], e.to));
}
}
}
}
}
priority_queue<node>que;
ll bfs(int u,int v){
que.push(node{u,0});
while(!que.empty()){
node tmp=que.top();
que.pop();
if(tmp.to==v){
k--;
if(k==0)return tmp.cost;
}
int now=tmp.to;
for(int i=0;i<G[now].size();i++){
que.push(node{G[now][i].second,tmp.cost+G[now][i].first});
}
}
return -1;
}