有限制的最短路问题
1.K 站中转内最便宜的航班
如果不考虑“最多经过K站”这个条件,这就是一道求最短路问题。
但是现在有了条件,就是有限制的最短路问题。我们考虑用dp来做。
可以看到当前状态,只与之前状态的 经过多少站,在哪一站 有关,因此是个二维dp
class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
final int INF = 10000 * 101 + 1;
//dp[i][j]相当于 经过i个站点,目前位于j站
int[][] dp=new int[k+2][n];
int res=INF;
Arrays.fill(dp[0],INF);
dp[0][src]=0;
//因为经过的站点数目一定是 递增 的,大的站点数目一定从小的站点数目转化而来,因此遍历可能经过的站点数
// 但是,不能保证 经过的站点是递增的,小的站点也有可能是从大的站点转化而来(比如 2号站点 去 1号站点)
for(int i=1;i<=k+1;i++){
//初始赋值,相当于所有边都没有路径
Arrays.fill(dp[i],INF);
for(int[] cur:flights){
int curSrc=cur[0];
int curDst=cur[1];
int cost=cur[2];
dp[i][curDst]=Math.min(dp[i-1][curSrc]+cost,dp[i][curDst]);
}
res=Math.min(dp[i][dst],res);
}
return res==INF?-1:res;
}
}
2.规定时间内到达终点的最小花费
class Solution {
public int minCost(int maxTime, int[][] edges, int[] passingFees) {
int INF=10000000;
int n=passingFees.length;
int[][] dp=new int[maxTime+1][n];
for(int i=0;i<=maxTime;i++){
Arrays.fill(dp[i],INF);
}
int res=INF;
dp[0][0]=passingFees[0];
//这里递增时间是因为,大的时间一定是从小的时间转化而来,但是小 的城市可能是从大的城市转化而来(比如 2号城市 去往 1号城市)
for(int i=0;i<=maxTime;i++){
for(int[] edge:edges){
int src=edge[0];
int dst=edge[1];
int time=edge[2];
if(i-time<0) continue;
//因为是双向图
dp[i][src]=Math.min(dp[i-time][dst]+passingFees[src],dp[i][src]);
dp[i][dst]=Math.min(dp[i-time][src]+passingFees[dst],dp[i][dst]);
}
res=Math.min(dp[i][n-1],res);
}
return res==INF? -1:res;
}
}
我有一壶酒
足以慰风尘
尽倾江海里
赠饮天下人