BD202301 公园(java)

百度之星BD202301 公园,使用Java


小度当前所在景点编号为 T,从一个景点到附近的景点需要消耗的体力是 TE,
而度度熊所在景点编号为 F ,移动消耗为 FE。
如果小度和度度熊一块移动(即在相同位置向相同方向移动),每一步他俩的总消耗将会减少 S。
求他俩到景点 N 时,所需要的总消耗最少是多少?

输入格式:

第一行三个数值,TE,FE,S ,分别代表小度移动消耗值,度度熊移动消耗值,一起移动的消耗减少值。1≤TE,FE,S≤40000, S ≤TE+FE。
第二行四个数值,T,F,N,M,分别代表小度出发点,度度熊出发点,目标节点,总路径数。1 ≤ T,F,N,M ≤40000
接下来 MM 行,每行两个整数 X,Y,代表连通的两个景点。1≤X,Y≤N。

输出格式:

一个整数,即总消耗最小值。如果不能到达 N , 输出-1。

样例
 输入:
        4 4 3
        1 2 8 8
        1 4
        2 3
        3 4
        4 7
        2 5
        5 6
        6 8
        7 8
输出:

        22

知识点:

邻接表

bfs算法

废话少说上代码

package example;
import java.util.ArrayList;
import java.util.Scanner;

public class bd01 {
    public static final int n = 40010;

    public static int TE, FE, S;
    public static int T, F, N, M;

    //创建动态数组v,大小n
    public static ArrayList<Integer>[] v = new ArrayList[n];  // 邻接表v,存储图的边信息
    //创建二维数组d,0—>小度,1—>熊,2—>终点
    public static int[][] d = new int[3][n]; // 小度、度度熊、终点到每个点的最短距离

    public static void bfs(int[] dist, int src)  // 求起点src到每个点的最短距离
    {
        /* bfs求最短路的模板 */
        int[] q = new int[n];//储存待处理节点
        // 初始化为-1,表示src不能直接到达这些节点
        for (int i = 1; i <= N; i++) dist[i] = -1;
        //表示队列头部,-1表示队列为空
        int hh = -1;
        //表示队列尾部,0表示队列中有一个元素
        int tt = 0;
        //设起点到自己距离0
        dist[src] = 0;
        //将起点 src 加入队列 q 中,同时更新 hh 的值,表示队列中有一个元素
        q[++hh] = src;

        while (hh <= tt)
        {
            //取出头部节点并将hh+1,表示取出一个节点
            int head = q[hh++];
            //遍历当前节点head的邻居节点
            for (int x : v[head])
            {
                //如果邻居节点的距离尚未确定
                if (dist[x] == -1)
                {
                    //将节点 x 的距离更新为当前节点 head 的距离加 1
                    // 表示从起点 src 经过节点 head 到达节点 x 的距离
                    dist[x] = dist[head] + 1;
                    //将节点 x 加入队列 q 的尾部,并更新 tt 的值,表示队列中多了一个元素
                    q[++tt] = x;
                }
            }
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        TE = scanner.nextInt();
        FE = scanner.nextInt();
        S = scanner.nextInt();
        T = scanner.nextInt();
        F = scanner.nextInt();
        N = scanner.nextInt();
        M = scanner.nextInt();

        for (int i = 1; i <= N; i++) {
            v[i] = new ArrayList<>();
        }

        for (int i = 0; i < M; i++)
        {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            v[a].add(b);
            v[b].add(a);
        }

        // 分别计算T、F、N到所有点的最短路径
        bfs(d[0], T);
        bfs(d[1], F);
        bfs(d[2], N);

        long ans = Long.MAX_VALUE;
        for (int i = 1; i <= N; i++)
        {
            // 这里要判断是否等于-1。如果等于-1,说明当前汇合点i不能到达T、F、N中的某个点
            if (d[0][i] != -1 && d[1][i] != -1 && d[2][i] != -1)
            {
                //创建一个名为distance的长整数变量,储存从i到达三个目标节点的距离之和
                //(long)强制类型转换,防止计算时溢出
                long distance = (long) d[0][i] * TE + (long) d[1][i] * FE + (long) d[2][i] * (TE + FE - S);
                ans = Math.min(ans, distance);
            }
        }

        if (ans == Long.MAX_VALUE) System.out.println(-1);
        else System.out.println(ans);
    }
}

其他:

最后细说一下main

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        TE = scanner.nextInt();
        FE = scanner.nextInt();
        S = scanner.nextInt();
        T = scanner.nextInt();
        F = scanner.nextInt();
        N = scanner.nextInt();
        M = scanner.nextInt();

        for (int i = 1; i <= N; i++) {
            v[i] = new ArrayList<>();
        }

        for (int i = 0; i < M; i++)
        {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            v[a].add(b);
            v[b].add(a);
        }

        // 分别计算T、F、N到所有点的最短路径
        bfs(d[0], T);
        bfs(d[1], F);
        bfs(d[2], N);

        long ans = Long.MAX_VALUE;
        for (int i = 1; i <= N; i++)
        {
            // 这里要判断是否等于-1。如果等于-1,说明当前汇合点i不能到达T、F、N中的某个点
            if (d[0][i] != -1 && d[1][i] != -1 && d[2][i] != -1)
            {
                //创建一个名为distance的长整数变量,储存从i到达三个目标节点的距离之和
                //(long)强制类型转换,防止计算时溢出
                long distance = (long) d[0][i] * TE + (long) d[1][i] * FE + (long) d[2][i] * (TE + FE - S);
                ans = Math.min(ans, distance);
            }
        }

        if (ans == Long.MAX_VALUE) System.out.println(-1);
        else System.out.println(ans);
    }

  1. 程序使用循环读取输入数据,构建图的邻接表。对于每个边,程序读取两个整数 ab,表示两个节点之间有一条边,然后将这条边添加到对应的 ArrayList 中。

  2. 接下来,程序调用 bfs 方法三次,分别计算从 TFN 到所有其他节点的最短距离,分别存储在 d[0]d[1]d[2] 数组中。

  3. 最后,程序使用一个循环遍历所有节点,计算满足条件的节点的距离之和,并找出最小的距离之和,将其存储在 ans 变量中。

  4. long distance = (long) d[0][i] * TE + (long) d[1][i] * FE + (long) d[2][i] * (TE + FE - S);:首先,代码创建一个名为 distance 的长整数(long)变量,用于存储从节点 i 到达三个目标节点的距离之和。这里使用强制类型转换 (long) 将整数值转换为长整数,以确保在计算距离之和时不会发生溢出。

    d[0][i] * TE 表示从节点 i 到目标节点 T 的距离乘以 TE

    d[1][i] * FE 表示从节点 i 到目标节点 F 的距离乘以 FE。 
    d[2][i] * (TE + FE - S) 表示从节点 i 到目标节点 N 的距离乘以 (TE + FE - S)

  5. ans = Math.min(ans, distance);接下来,代码比较当前的最小距离 ans 与计算得到的 distance,并将较小的值存储回 ans 中。这样,ans 会始终保持为已经计算过的路径中的最小距离。

  6. 最后,程序根据 ans 的值输出结果,如果 ans 仍然等于 Long.MAX_VALUE,则输出 -1,否则输出 ans 的值。

最后:

在网站提交时,public class类的名字一定要写Main或main

猜你喜欢

转载自blog.csdn.net/m0_74137767/article/details/132872672
BD