算法:
我们设dis[i][j]表示从t到i的路,搭乘了j次飞机的最小费用,接着我们利用SPFA进行状态的转移即可,
答案即为max{dis[t][i](0<=i<=k)}。(考虑到k可能大于路径的条数。)
Code:
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
template<typename T> void read(T &num){
char c=getchar();num=0;T f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){num=(num<<3)+(num<<1)+(c^48);c=getchar();}
num*=f;
}
template<typename T> void qwq(T x){
if(x>9)qwq(x/10);
putchar(x%10+'0');
}
template<typename T> void write(T x){
if(x<0){x=-x;putchar('-');}
qwq(x);putchar('\n');
}
template<typename T> void chkmin(T &x,T y){x=x<y?x:y;}
int n,m,k,s,t;
struct wzy{
int nxt,vertice,w;
}edge[100010];
int head[10010];int len=0;
inline void add_edge(int x,int y,int z){
edge[++len].nxt=head[x];edge[len].vertice=y;
edge[len].w=z;head[x]=len;return;
}
priority_queue<pair<int,pair<int,int> > >v;
int dis[10010][15];bool in[10010][15];
inline void SPFA(){
rep(i,1,n){
rep(j,0,k){dis[i][j]=INT_MAX;}
}
v.push(make_pair(0,make_pair(s,0)));in[s][0]=1;dis[s][0]=0;
while(!v.empty()){
int nop1=v.top().second.first;int nop2=v.top().second.second;
in[nop1][nop2]=0;v.pop();
for(int i=head[nop1];i;i=edge[i].nxt){
int temp=edge[i].vertice;
if(dis[nop1][nop2]+edge[i].w<dis[temp][nop2]){
dis[temp][nop2]=dis[nop1][nop2]+edge[i].w;
if(!in[temp][nop2]){
v.push(make_pair(-dis[temp][nop2],make_pair(temp,nop2)));
in[temp][nop2]=1;
}
}
if(nop2==k)continue;
if(dis[nop1][nop2]<dis[temp][nop2+1]){
dis[temp][nop2+1]=dis[nop1][nop2];
if(!in[temp][nop2+1]){
v.push(make_pair(-dis[temp][nop2+1],make_pair(temp,nop2+1)));
in[temp][nop2+1]=1;
}
}
}
}
return;
}
int main(){
read(n);read(m);read(k);read(s);read(t);s++;t++;
rep(i,1,m){
int a,b,c;read(a);read(b);read(c);
add_edge(a+1,b+1,c);add_edge(b+1,a+1,c);
}
SPFA();
int ans=INT_MAX;
rep(i,0,k){chkmin(ans,dis[t][i]);}
write(ans);
return 0;
}