dp[u][t]表示从起点出发,到达i点且用了t次magic boot时的最短时间,
方程如下:
dp[v][t]=min(dp[v][t],dp[u][t]+dis[u][v]);
dp[v][t]=min(dp[v][t],dp[u][t-1]) (dis[u][v]<=l)
放进SPFA更新,相当于一个二维的最短路,解决DP在非DAG下的有后效性的问题。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 111 7 #define INF (1<<29) 8 9 int n,a,b,m,l,k; 10 int map[MAXN][MAXN],dis[MAXN][MAXN]; 11 12 void Floyd(){ 13 memcpy(dis,map,sizeof(map)); 14 for(int k=1; k<=a; ++k){ 15 for(int i=1; i<=n; ++i){ 16 for(int j=1; j<=n; ++j){ 17 if(dis[i][k]==INF || dis[k][j]==INF) continue; 18 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); 19 } 20 } 21 } 22 } 23 24 struct QNode{ 25 int u,t; 26 QNode(int _u=0,int _t=0):u(_u),t(_t){} 27 }; 28 int dp[MAXN][11]; 29 bool vis[MAXN][11]; 30 void SPFA(){ 31 memset(vis,0,sizeof(vis)); 32 vis[n][0]=1; 33 for(int i=1; i<=n; ++i){ 34 for(int j=0; j<11; ++j) dp[i][j]=INF; 35 } 36 dp[n][0]=0; 37 queue<QNode> que; 38 que.push(QNode(n,0)); 39 while(!que.empty()){ 40 int u=que.front().u,t=que.front().t; 41 que.pop(); 42 for(int v=1; v<=n; ++v){ 43 if(dp[v][t]>dp[u][t]+dis[u][v]){ 44 dp[v][t]=dp[u][t]+dis[u][v]; 45 if(!vis[v][t]){ 46 vis[v][t]=1; 47 que.push(QNode(v,t)); 48 } 49 } 50 } 51 for(int v=1; t!=k && v<=n; ++v){ 52 if(dis[u][v]<=l && dp[v][t+1]>dp[u][t]){ 53 dp[v][t+1]=dp[u][t]; 54 if(!vis[v][t+1]){ 55 vis[v][t+1]=1; 56 que.push(QNode(v,t+1)); 57 } 58 } 59 } 60 vis[u][t]=0; 61 } 62 } 63 64 int main(){ 65 int t,u,v,w; 66 scanf("%d",&t); 67 while(t--){ 68 scanf("%d%d%d%d%d",&a,&b,&m,&l,&k); 69 n=a+b; 70 for(int i=1; i<=n; ++i){ 71 for(int j=1; j<=n; ++j) map[i][j]=INF; 72 } 73 while(m--){ 74 scanf("%d%d%d",&u,&v,&w); 75 map[u][v]=map[v][u]=min(map[u][v],w); 76 } 77 Floyd(); 78 SPFA(); 79 int res=INF; 80 for(int i=0; i<=k; ++i){ 81 res=min(res,dp[1][i]); 82 } 83 printf("%d ",res); 84 } 85 return 0; 86 }