本题要求最多经过 k 个城市的条件下,从城市 src 到城市 dst 的最低运输成本。

在之前的Bellman_ford朴素算法中,我们是对所有边 松弛了 n-1 次,就一定可以得到 从源点出发 总共走n-1条边 到达终点的 最短距离。

那么本题是最多经过k个城市,换句话来说实际上是走了n + 1 条边。

上图所示,从节点1走到节点4 ,经过了两个节点,但是走了三条边。

所以本题可以简化为:起点最多经过 k + 1条边到达终点的最短距离。

在原有的Bellman_ford算法代码基础上松弛k + 1次即可。

但是在松弛k + 1 次过程中,没有体现最多经过 k 个城市 这一附加条件。造成在更新minDist数组时,在同一轮松弛过程中,使用了当前轮次的松弛的minDist结果,但这是不对的。每松弛轮更新的minDist数组是上一轮松弛的minDist的值才可以。

因此每次判断更新minDist数组时,要拿上一轮的minDist数组和当前轮的minDist数组比较才可以

完整代码如下:

import java.util.*;

public class Main{
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        //存储所有的边
        List<Edge> edges = new ArrayList<>();
        for(int i = 0; i < m; i++){
            int s = scanner.nextInt();
            int t = scanner.nextInt();
            int v = scanner.nextInt();
            edges.add(new Edge(s, t, v));
        }
        int src = scanner.nextInt();
        int dst = scanner.nextInt();
        int k = scanner.nextInt();
        //minDist数组
        int[] minDist = new int[n + 1];
        for(int i = 0; i < minDist.length; i++){
            minDist[i] = Integer.MAX_VALUE;
        }
        //设置src为源点,所以节点src到源点的距离初始化为0
        minDist[src] = 0;
        int[] minDistCopy = new int[n + 1];
        //对所有边松弛 k + 1次
        for(int i = 0; i <= k; i++){
            //对minDist进行复制,
            //防止在同一轮松弛过程中,更新边的时候用到了当前轮更新过的minDist
            minDistCopy = Arrays.copyOf(minDist, n+1);
            for(Edge edge : edges){
                if(minDistCopy[edge.from] != Integer.MAX_VALUE && minDistCopy[edge.from] + edge.val < minDist[edge.to]){
                    minDist[edge.to] = minDistCopy[edge.from] + edge.val;                }
            }
        }
       
        if(minDist[dst] == Integer.MAX_VALUE){
            System.out.print("unreachable");
        }else{
            System.out.print(minDist[dst]);
        }  
    }    
}

class Edge{
    public int from;
    public int to;
    public int val;
    public Edge(int from, int to, int val){
        this.from = from;
        this.to = to;
        this.val = val;
    }
}

Categories:

Tags:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注