有限制的最短路问题

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;


    }
}
posted @ 2021-08-24 16:07  刚刚好。  阅读(160)  评论(0编辑  收藏  举报