link:https://vjudge.net/problem/POJ-2449
前面输入与大多最短路题相同
最后一行输入s,t,k 求从s到t的第K短路
wiki link: https://en.wikipedia.org/wiki/A*_search_algorithm
出题者的算法是首先计算任意一点到终点的最短距离,使用这个距离作为A*算法中H函数(从当前点到终点的估计函数)使用A*算法。跟一般的A*算法不同的是,一个结点可以被多次扩展到(A*算法中只保留到达一个结点的最短路径)。使用这个算法就可以得到起点到终点的最短路径,第二短路径,第三短路径……
复杂度很难算清楚,但是非常低。
#include <iostream> #include <cstring> #include <queue> using namespace std; const int MAXN=1010; struct node { int p,g,h; bool operator < (node a) const { return a.g+a.h<g+h; } }; struct node1 { int x,y,w,next; }line[MAXN*100],line1[MAXN*100]; int n,m,i,link[MAXN],link1[MAXN],g[MAXN],s,e,k; bool used[MAXN]; priority_queue<node> myqueue; void djikstra() { int i,k,p; memset(used,0,sizeof(used)); memset(g,0x7F,sizeof(g)); g[e]=0; for (p=1;p<=n;p++) { k=0; for (i=1;i<=n;i++) if (!used[i] && (!k || g[i]<g[k])) k=i; used[k]=true; k=link1[k]; while (k) { if (g[line1[k].y]>g[line1[k].x]+line1[k].w) g[line1[k].y]=g[line1[k].x]+line1[k].w; k=line1[k].next; } } return ; } int Astar() { int t,times[MAXN]; node h,temp; while(!myqueue.empty()) myqueue.pop(); memset(times,0,sizeof(times)); h.p=s;h.g=0;h.h=0;myqueue.push(h); while(!myqueue.empty()) { h=myqueue.top(); myqueue.pop(); times[h.p]++; if(times[h.p]==k&&h.p==e) return h.h+h.g; if(times[h.p]>k) continue; t=link[h.p]; while(t) { temp.h=h.h+line[t].w; temp.g=g[line[t].y]; temp.p=line[t].y; myqueue.push(temp); t=line[t].next; } } return -1; } int main() { ios::sync_with_stdio(false); cin>>n>>m; memset(link,0,sizeof(link)); memset(link1,0,sizeof(link1)); for(int i=1;i<=m;i++) { cin>>line[i].x>>line[i].y>>line[i].w; line[i].next=link[line[i].x]; link[line[i].x]=i; line1[i].x=line[i].y; line1[i].y=line[i].x; line1[i].w=line[i].w; line1[i].next=link1[line1[i].x]; link1[line1[i].x]=i; } cin>>s>>e>>k; if(s==e) k++; djikstra(); cout<<Astar()<<endl; return 0; }