蓝桥训练营-大臣的旅费(java)(树中权值和最大的通路)

题目:

问题描述

很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。

为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。

J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。

聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。

J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?

输入格式

输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数

城市从1开始依次编号,1号城市为首都。

接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)

每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。

输出格式

输出一个整数,表示大臣J最多花费的路费是多少。

样例输入1

5
1 2 2
1 3 1
2 4 5
2 5 4

样例输出1

135

思路:

  1. 题目的意思就是求哪两个城市之间的距离最大,特别要注意的一点是题目中描述的是:任何一个大城市都能从首都直接或者通过其他大城市间接到达,这样就很容易抽象成一个树状结构了,没有两个城市是直接相连的,都是经过首都或者其他城市间接相连的。

  2. 这样就转化成了求树中权值和最大的通路, 我们可以通过从某个点开始找到离他最远的一个点作为起点,再以该起点去找离该起点最远的某个点,这样就是一条最远的通路了

  3. 这里如果用邻接矩阵去存树信息的话会内存超限,所以这里使用邻接表的形式进行存储

Code:

import java.util.Scanner;
import java.util.*;


public class Main{
    static int[] arr;
    static int[] visit;
    static int m;
    private static int count=0;
    static int max=0;
    static int a=0;
    static List<int[]> []listmap;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n=scanner.nextInt();
        listmap=new ArrayList[n+1];
        visit=new int[n+1];
        visit[1]=1;
        for (int i=1;i<=n;i++){
            listmap[i]=new ArrayList<>();
        }
        for (int i=0;i<n-1;i++){
            int x=scanner.nextInt();
            int y=scanner.nextInt();
            int z=scanner.nextInt();
            listmap[x].add(new int[]{y,z});
            listmap[y].add(new int[]{x,z});
        }
        // 直观打印邻接表
//        for (int i=1;i<=n;i++){
//            List<int[]> ints = listmap[i];
//            for (int[] arr:ints){
//                System.out.print(arr[0]+" "+ arr[1]+" ");
//            }
//            System.out.println();
//        }
        dfs(1,0);
//        System.out.println(a);
        visit=new int[n+1];
        max=0;
        visit[a]=1;
        dfs(a,0);
        System.out.println((max+10+11)*max/2);
    }

    private static void dfs(int point, int dis) {
        if (dis>max){
            a=point;
            max=dis;
        }
        for (int i = 0; i <listmap[point].size(); i++) {
            int y=listmap[point].get(i)[0];
            if (visit[y]==1) continue;
            visit[y]=1;
            dis+=listmap[point].get(i)[1];
            dfs(y,dis);
            visit[y]=0;
            dis-=listmap[point].get(i)[1];
        }
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值