之前一直想寫一下A*,K短路的模板,然後看到了這題,於是各種敲代碼的欲望湧上來。
知道A*的人應該都知道可以用A*來求最短路,當終點節點第K次出隊時,就是第K短路。
而A*的關鍵在於求估價函數,所以可以一遍反向SPFA求得終點到每個點的最短路,作為估價函數。【還是自己的模板比較好看】
#include#include #include #include #include #include #include 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 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 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; }