A*算法
A*算法中最关键肯定是f=g+h。估价函数h,代价函数g。
每次取出f最小的,然后开始更新周围的节点。
对于未到达的节点直接更新,已到达的节点用g值比较一下,更优则更新。
而估价函数在一开始就算好了。
那么对于k短路问题呢。
首先预处理出终点t到每个点的最短路,即为估价函数h。(最常用的做法)
然后从起点出发,代价什么的走的时候算一下就好了。
于是当经过一个节点k次的时候就是该节点的第k短路。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn=100005; const int inf=1e9; struct Edge{ int to,next,v; }g[maxn],gt[maxn]; int head[1005],headt[1005],cnt,cntt; void addedge(int u,int v,int w) { g[++cnt]=(Edge){v,head[u],w}; head[u]=cnt; gt[++cntt]=(Edge){u,headt[v],w}; headt[v]=cntt; } struct Dijnode { int x,d; Dijnode(int a,int b):x(a),d(b){} bool operator < (const Dijnode &a) const{ return d>a.d; } }; int dis[1005]; bool vis[1005]; void dijkstra(int s){ memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[s]=0; priority_queue<Dijnode>q; q.push(Dijnode(s,0)); while(!q.empty()){ Dijnode x=q.top(); q.pop(); int u=x.x; if(vis[u]) continue; vis[u]=true; for(int i=headt[u];i;i=gt[i].next){ int v=gt[i].to; if(dis[v]>dis[u]+gt[i].v){ dis[v]=dis[u]+gt[i].v; q.push(Dijnode(v,dis[v])); } } } } struct Anode { int f,g,v; Anode(int a,int b,int c):f(a),g(b),v(c){} bool operator < (const Anode &a) const{ return f>a.f; } }; int inq[1005]; int A_star(int s,int t,int k){ priority_queue<Anode>q; if(dis[s]>inf) return -1; memset(inq,0,sizeof(inq)); q.push(Anode(dis[s],0,s)); while(!q.empty()){ Anode x=q.top(); q.pop(); int u=x.v; inq[u]++; if(inq[t]==k) return x.f; if(inq[u]>k) continue; for(int i=head[u];i;i=g[i].next){ int v=g[i].to,w=g[i].v; q.push(Anode(dis[v]+w+x.g,x.g+w,v)); } } return -1; } template<class T>void read(T &x){ static char c; static bool f; for(f=0;c=getchar(),!isdigit(c);)if(c=='-')f=1; for(x=0;isdigit(c);c=getchar())x=x*10+c-'0'; if(f)x=-x; } int main(){ int n,m;read(n);read(m); int u,v,w; for(int i=1;i<=m;i++){ read(u);read(v);read(w); addedge(u,v,w); } int s,t,k;read(s);read(t);read(k); dijkstra(t); if(s==t)k++; printf("%d",A_star(s,t,k)); return 0; }
短路了。