之前一直想写一下A*,K短路的模板,然后看到了这题,于是各种敲代码的欲望涌上来。
知道A*的人应该都知道可以用A*来求最短路,当终点节点第K次出队时,就是第K短路。
而A*的关键在于求估价函数,所以可以一遍反向SPFA求得终点到每个点的最短路,作为估价函数。【还是自己的模板比较好看】
#include<iostream> #include<cstdlib> #include<cstring> #include<cmath> #include<cstdio> #include<algorithm> #include<queue> using namespace std; #define maxn 5005 #define maxm 200005 struct node { int v,w,next; }edge[maxm]; int head[maxn]; bool in[maxn]; int d[maxn]; int cnt[maxn]; int a,b,c,n,m,id; void add(int a,int b,int c) { edge[id].v=b; edge[id].w=c; edge[id].next=head[a]; head[a]=id++; } void init() { memset(head,-1,sizeof(int)*(n+1)); id=0; } void SPFA(int st) { queue<int> Q; memset(in,0,sizeof(int)*(n+1)); memset(d,0x3f,sizeof(int)*(n+1)); memset(cnt,0,sizeof(int)*(n+1)); Q.push(st); in[st]=1; d[st]=0; int tmp; while(!Q.empty()) { tmp=Q.front();Q.pop(); in[tmp]=0; for(int i=head[tmp];i!=-1;i=edge[i].next) { if(d[edge[i].v]>d[tmp]+edge[i].w) { d[edge[i].v]=d[tmp]+edge[i].w; if(!in[edge[i].v]) { in[edge[i].v]=1; Q.push(edge[i].v); } } } } } struct node2 { int h; int far; int u; bool operator <(const node2&X) const { return h+far>X.h+X.far; } }; int AS(int st,int ed,int k) { priority_queue<node2> Q; node2 t,f; t.h=d[st]; t.far=0; t.u=st; Q.push(t); while(!Q.empty()) { f=Q.top();Q.pop(); cnt[f.u]++; if(cnt[f.u]>k) continue; if(cnt[ed]==k) return f.far; for(int i=head[f.u];i!=-1;i=edge[i].next) { t.far=f.far+edge[i].w; t.u=edge[i].v; t.h=d[edge[i].v]; Q.push(t); } } return -1; } int main() { while(~scanf("%d%d",&n,&m)) { init(); for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } SPFA(n); printf("%d\n",AS(1,n,2)); } return 0; }