PREV-9-蓝桥杯-历届试题-大臣的旅费

这道题我也不会写,然后参考了这篇---->

出自:https://www.cnblogs.com/tonghao/p/4740425.html

要用两次DFS求最长的距离。

而最远的点G-D,他们之间的距离即整棵树距离最长。

这里默认他们的权值为1,只是为了说明原理,具体搜索要根据路径的权值来定。

先给出所有的代码,然后对代码各部分进行详细解释。

 1 import java.util.ArrayList;
 2 import java.util.Arrays;
 3 import java.util.Scanner;
 4 
 5 //动态链表
 6 class Vertex{
 7     ArrayList<Integer> V=new ArrayList();
 8 }
 9 class Edge{
10     ArrayList<Integer> E=new ArrayList();
11 }
12 
13 public class Main {
14     final static int INF=0X3f3f3f3f;//10^9一般数都达不到这个,所以用它作为最大值
15     final static int maxn=100000;
16     static Vertex[] v=new Vertex[maxn+5];//V[i]存储与i相邻接的节点
17     static Edge[] e=new Edge[maxn+5];//e[i]存储与i邻接的边的距离
18     static boolean vis[]=new boolean[maxn+5];//防止重复访问
19     static int dis[]=new int[maxn+5];//存储原始结点到各结点的dfs距离
20     
21     static void init(int n){//初始化
22         for(int i=0;i<n;i++){
23             v[i]=new Vertex();//为每个城市都创建一条链表,用来记录它所能邻接的城市
24             e[i]=new Edge();
25         }
26     }
27     
28     static void dfs(int a){
29         int len=v[a].V.size();//与a相邻接的城市有几个
30         vis[a]=true;//a城市已经访问
31         for(int i=0;i<len;i++){//遍历城市
32             int j=v[a].V.get(i);//依次获取a邻接的几个城市
33             if(!vis[j]&&e[a].E.get(i)!=INF){
34                 vis[j]=true;
35                 dis[j]=dis[a]+e[a].E.get(i);
36                 dfs(j);
37                 vis[j]=false;//回溯
38             }
39         }
40     }
41     
42     public static void main(String[] args) {
43         Scanner sc=new Scanner(System.in);
44         int n=sc.nextInt();
45         
46         init(n);
47         
48         for(int i=0;i<n-1;i++){
49             int a=sc.nextInt()-1;
50             int b=sc.nextInt()-1;
51             int c=sc.nextInt();
52             v[a].V.add(b);//a城市可以到b,所以,在他的链表里添加b
53             e[a].E.add(c);//用e记录对应的a-b的距离
54             v[b].V.add(a);//反之b可以到a
55             e[b].E.add(c);//用e记录对应的b-a的距离
56         }
57         
58         //此类包含用来操作数组(比如排序和搜索)的各种方法
59         //将制定的false,INF分配给对应数组中的每个元素,相当于for初始操作的简化
60         Arrays.fill(vis,false);
61         Arrays.fill(dis,INF);    
62         
63         dis[0]=0;
64         dfs(0);//第一次遍历  求得某个城市到最远的城市的最大距离是多少,并用dis[]来记录  比如sid[1]=67;
65         long max=-1;
66         int temp=-1;
67         for(int i=0;i<n;i++){
68             if(dis[i]>max){
69                 max=dis[i];
70                 temp=i;
71             }
72         }
73         
74         Arrays.fill(vis, false);
75         Arrays.fill(dis, INF);
76         
77         dis[temp]=0;
78         dfs(temp);//第二次遍历 求b与?距离最远
79         long ans=-1;//防止越界
80         for(int i=0;i<n;i++){
81             if(dis[i]>ans){
82                 ans=dis[i];
83                 temp=i;
84             }
85         }
86         ans=ans*(ans+21)/2;
87         System.out.println(ans);
88         sc.close();
89         
90     }
91  
92 }

自定义两个类,分别构造了动态链表。

INF=0X3f3f3f3f 可自行百度,简洁意思就是0X3f3f3f3f即十进制的 10的9次方,表示一个超大的数,一般情况都达不到。此处用作后面作为一个标志。

maxn 作用可能是因为在蓝桥杯提交检测时最后输入的n是10000;所以在初始定义的时候就先创建一个比10000大的范围,所以 后面用了 maxn+5

init(n)就是确定具体的动态链表多长

看main方法中:

DFS深度优先搜索:

在之前,先把数据准备好,

执行过程——> 可能有些乱。。但花了很久时间。

第一次dfs结束后,dis[ ]存储了0到各城市的距离,在之后的操作中就是得到最远距离max,且用temp记录下与0最远的城市,也就是城市4,下标为3

 第二次遍历就是从3开始了。这次要找到距离3最远的城市。步骤原理同上,

这是第二次DFS结束,可以看出最远的应该是dis[4] 距离为9

然后进行最后的计算就可以得出所花费的钱了。

好像代码里的注解会有些错误,因为代码里的注释不是最后的理解,有错好像没更改过来?

猜你喜欢

转载自www.cnblogs.com/xly1997/p/10585038.html