题目![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/12e46bc9f9b12a8af807c3718e3d4bf7.png)
思路
https://www.redblobgames.com/pathfinding/a-star/introduction.html
代码
先include一下有优先队列的头文件
double cost[maxn][maxn];
double A_star(int s, int t)
{
int INF = 0x3f3f3f3f;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cost[i][j] = INF;
if (edge[i][j])
{
cost[j][i] = cost[i][j] = distance(i, j);
}
}
}
// open表,小顶堆
// <double,int>:f值,点编号(优先队列排序先以第一关键词排序,第一关键词相等再比较第二关键字)
priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> frontier;
// 先放入起点,起点的f值为0
pair<double, int> tmp(0, s);
frontier.push(tmp);
// close表
// <int,double>:点编号,g值
map<int, double> cost_so_far;
// 起点的g值为0
cost_so_far[s] = 0;
// 起点没有父节点
pos[s] = -1;
// 当open表非空
while (!frontier.empty())
{
// current为优先队列表头,即f值最小的结点
int current = frontier.top().second;
frontier.pop();
if (current == t)
{
// 终点h=0
return cost_so_far[current];
}
// 寻找相邻点,即待放入open表中的点
for (int next = 0; next < n; next++)
{
// 有边,next为与current相邻的点
if (cost[next][current] < INF)
{
// 求next的g
double new_cost = cost_so_far[current] + cost[current][next];
// next不在close中或新g比原来的路径更佳
if (cost_so_far.count(next) == 0 || new_cost < cost_so_far[next])
{
// 更新next的g值
cost_so_far[next] = new_cost;
// 求next的f值
// 注意此处使用distance作为h值,不是cost[next][t]
double priority = new_cost + distance(next, t);
// next进入open表
pair<double, int> tmp(priority, next);
frontier.push(tmp);
// 更新next的父节点
pos[next] = current;
}
}
}
}
}