A*搜索(bfs剪枝),评估函数由dijkstra给出,即从终点跑一遍dijkstra.然后从起点跑bfs,bfs设一个优先队列(按f值从小到大取出),每次入点时算一下f值,f=g+h,g为起点到当前点的实际距离,h为当前点到终点的估计距离,这里用之前跑的dijkstra来充当h.即f(i)=g(i)+d[i].当这个bfs第i次抵达终点算出来的就是第k短路.需要注意的是如果是有向图从终点跑的话需要把边反向,不然会卡死.
typedef pair<int,int> P; struct edge { int to,cost; edge (){} edge (int x,int y){to=x,cost=y;} }; vector<edge> es[MAX+1]; int d[MAX+1]; int n,m; void add(int s,int t,int c) //这里写的是无向图,有向图记得dijkstra要跑反边 { es[s].push_back(edge(t,c)); es[t].push_back(edge(s,c)); return ; } void dijkstra(int s) //从终点开始跑 { priority_queue<P,vector<P>,greater<P> > que; fill(d+1,d+n+1,INF); //点编号从1开始 d[s]=0; que.push(P(0,s)); //first为当前最短距离,seocnd为点 while(que.size()) { P p=que.top();que.pop(); int x=p.second; if(d[x]<p.first) continue; for(int i=0;i<es[x].size();i++) { edge e=es[x][i]; if(d[e.to]>d[x]+e.cost) { d[e.to]=d[x]+e.cost; que.push(P(d[e.to],e.to)); } } } } int bfs(int s,int k) //起点为s,求第k短路 { priority_queue<P,vector<P>,greater<P> > que; que.push(P(0+d[s],s)); //first是f值,second是点 int cnt=k; while(que.size()) { P p=que.top();que.pop(); int x=p.second; if(x==n) { cnt--; if(!cnt) return p.first-d[x]; } for(int i=0;i<es[x].size();i++) { edge e=es[x][i]; que.push(P(p.first-d[x]+e.cost+d[e.to],e.to)); } } }
原文:https://www.cnblogs.com/VBEL/p/10714884.html