题解:
spfa最短路径
dp[i][j]表示到i,用了j掌权
然后转移
代码:
#include<bits/stdc++.h> using namespace std; const int N=105; int n,m,k,in1,in2,in3,f[N][N],ans=1e9,used[N]; vector<pair<int,int> > graph[N]; queue<int> q; void spfa(int s) { for (int i=1;i<=n;i++) for (int j=0;j<=k;j++)f[i][j]=1e9; f[s][0]=0; used[s]=1; q.push(s); while (!q.empty()) { int x=q.front(),len=graph[x].size(); q.pop(); used[x]=0; for (int i=0;i<len;i++) { int relaxed=0; int t=graph[x][i].first,w=graph[x][i].second; for (int j=0;j<=k;j++) { if(f[t][j]>f[x][j]+w) f[t][j]=f[x][j]+w,relaxed=1; if(j&&f[t][j]>f[x][j-1]+(w>>1)) f[t][j]=f[x][j-1]+(w>>1),relaxed=1; } if (relaxed&&!used[t]) { used[t]=1; q.push(t); } } } } int main() { scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=m;i++) { scanf("%d%d%d",&in1,&in2,&in3); graph[in1].push_back(make_pair(in2,in3)); graph[in2].push_back(make_pair(in1,in3)); } spfa(1); for(int i=0;i<=k;i++)ans=min(ans,f[n][i]); printf("%d\n",ans); }