https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/
思路:经典
d
p
dp
dp题想歪wa半天。考虑
d
p
i
,
j
dp_{i,j}
dpi,j表示经过
i
i
i条边后到达点
j
j
j的最便宜的价格。显然有
d
p
0
,
s
r
c
=
0
dp_{0,src}=0
dp0,src=0,最终答案就是
m
i
n
i
,
d
s
t
min_{i,dst}
mini,dst,其中
0
<
=
i
<
=
k
+
1
0<=i<=k+1
0<=i<=k+1。怎么转移呢?其实方式有很多种,最直观的方式就是对于每个
i
i
i,遍历每一条边计算:
d
p
i
,
j
=
m
i
n
(
d
p
i
,
j
,
d
p
i
−
1
,
k
+
c
o
s
t
k
,
j
)
i
f
E
k
,
j
i
n
E
dp_{i,j}=min(dp_{i,j},dp_{i-1,k}+cost_{k,j})\ if\ E_{k,j}\ in\ E
dpi,j=min(dpi,j,dpi−1,k+costk,j) if Ek,j in E
也可以仅对于
i
−
1
i-1
i−1中出现的状态进行扩展。
class Solution {
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
using pr=pair<int,int>;
vector<vector<pr>> graph(n);
for(vector<int>& flight:flights)
graph[flight[0]].emplace_back(flight[1],flight[2]);
int inf=0x3f3f3f3f;
vector<vector<int>> dp(k+2,vector<int>(n,inf));
dp[0][src]=0;
int ans=inf;
for(int i=0;i<=k;i++)
{
for(int j=0;j<n;j++)
{
if(dp[i][j]==inf)
continue;
for(pr& nxt:graph[j])
dp[i+1][nxt.first]=min(dp[i+1][nxt.first],dp[i][j]+nxt.second);
}
ans=min(ans,dp[i][dst]);
}
ans=min(ans,dp[k+1][dst]);
return ans==inf?-1:ans;
}
};