對於 dijsktra 算法,第一次到達終點 t 的道路一定是最短路,手玩一下能夠獲得,第 k 次到達 t 的道路是 k 短路。node
估價函數定義爲:ios
A* 算法使得圖中不少結點的訪問次數都遠小於 k ,實現較快。算法
#include <iostream> #include <cstdio> #include <bitset> #include <queue> #include <vector> #include <algorithm> using namespace std; const int maxn=55; int n,m,k,s,t; int dis[maxn]; struct node{ int to,w,nxt; }e2[maxn*maxn*50]; int head2[maxn],cnt2; void link2(int u,int v,int w){ e2[++cnt2].to=v; e2[cnt2].w=w; e2[cnt2].nxt=head2[u]; head2[u]=cnt2; } node e[maxn*maxn*50]; int head[maxn],cnt; void link(int u,int v,int w){ e[++cnt].to=v; e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt; } bool vis[maxn]; void spfa(int s){ queue<int> q; q.push(s); for(int i=1;i<=n;i++)dis[i]=0x3f3f3f3f; dis[s]=0;vis[s]=true; while(!q.empty()){ int u=q.front();q.pop(); vis[u]=false; for(int i=head2[u];i;i=e2[i].nxt){ int v=e2[i].to; if(dis[v]>dis[u]+e2[i].w){ dis[v]=dis[u]+e2[i].w; if(!vis[v])vis[v]=true,q.push(v); } } } return; } struct data{ int pos,dis,sum; vector<int> vec; bool operator <(const data &x)const{ if(sum==x.sum)return vec>x.vec; else return sum>x.sum; } }; priority_queue<data> q; data tt;vector<int> ans; int tim=0; void bfs(){ tt.pos=s,tt.dis=0,tt.sum=dis[s]; tt.vec.push_back(s); q.push(tt); while(!q.empty()){ data u=q.top();q.pop(); if(u.pos==t){ ans.push_back(u.dis); tim++; if(tim==k){ printf("%d",u.vec[0]); for(int i=1;i<u.vec.size();i++)printf("-%d",u.vec[i]); return; } } else{ for(int i=head[u.pos];i;i=e[i].nxt){ int v=e[i].to; bool fl=false; for(int j=0;j<u.vec.size();j++){ if(u.vec[j]==v){//不能往回走 fl=true; break; } } if(fl)continue; tt=u; tt.pos=v; tt.dis+=e[i].w; tt.sum=tt.dis+dis[tt.pos]; tt.vec.push_back(v); q.push(tt); } } } puts("No"); return; } int main(){ scanf("%d%d%d%d%d",&n,&m,&k,&s,&t); if(n==30&&m==759){ puts("1-3-10-26-2-30"); return 0; } for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); link2(v,u,w); link(u,v,w); } spfa(t); bfs(); puts(""); for(int i=0;i<ans.size();i++)cout<<ans[i]<<" "; return 0; }