Topic connection: https://ac.nowcoder.com/acm/contest/904/D
The first study about this type of exercise, it is quite easy to understand, because the limited number of half-price, so in each case should be written every one, dp [Position] [number] pushed to dp [arrival location] [times] and dp [reach the position] [number of + 1] in both cases, and then click the shortest run on it
AC Code:
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef struct W_W{ int eend; int weight; int next; }miao; typedef struct W_w{ int eend; int ci; }wang; ll minn(ll a,ll b){ if(a<b) return a; return b; } miao x[100010]; int head[100010]; ll dp[100010][15]; int vis[100010][15]; int cnt=0; void add(int a,int b,int c){ x[cnt].eend=b; x[cnt].weight=c; x[cnt].next=head[a]; head[a]=cnt++; } ll spfa(int start,int eend,int k){ queue<wang> q1; q1.push({1,0}); dp[1][0]=0; while(q1.size()){ int dang=q1.front().eend; int ci=q1.front().ci; //printf("+++%d %d %lld \n",dang,ci,dp[dang][ci]); q1.pop(); vis[dang][ci]=0; for(int i=head[dang];i!=-1;i=x[i].next){ int to=x[i].eend; if(dp[to][ci]==-1){ dp[to][ci]=dp[dang][ci]+x[i].weight; if(vis[to][ci]==0){ q1.push({to,ci}); vis[to][ci]=1; } } else{ if(dp[to][ci]>dp[dang][ci]+x[i].weight){ dp[to][ci]=dp[dang][ci]+x[i].weight; if(vis[to][ci]==0){ q1.push({to,ci}); vis[to][ci]=1; } } } if(ci+1<=k){ if(dp[to][ci+1]==-1){ dp[to][ci+1]=dp[dang][ci]+x[i].weight/2; if(vis[to][ci+1]==0){ q1.push({to,ci+1}); vis[to][ci+1]=1; } } else{ if(dp[to][ci+1]>dp[dang][ci]+x[i].weight/2){ dp[to][ci+1]=dp[dang][ci]+x[i].weight/2; if(vis[to][ci+1]==0){ q1.push({to,ci+1}); vis[to][ci+1]=1; } } } } } } // for(int i=1;i<=eend;i++){ // for(int j=0;j<=k;j++){ // printf("(%d %d) %lld ",i,j,dp[i][j]); // } // printf("\n"); // } ll ans=-1; for(int i=0;i<=k;i++){ // printf("+++%lld %d %d %lld\n",ans,eend,i,dp[eend][i]); if(dp[eend][i]!=-1){ if(ans==-1){ ans=dp[eend][i]; } else{ ans=minn(dp[eend][i],ans); } } } return ans; } int main() { int m,n,k; scanf("%d %d %d",&m,&n,&k); memset(head,-1,sizeof(head)); memset(dp,-1,sizeof(dp)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ int a,b; int c; scanf("%d %d %d",&a,&b,&c); add(a,b,c); } ll ans=spfa(1,m,k); printf("%lld\n",ans); return 0; }