这道题我也不会写,然后参考了这篇---->https://blog.csdn.net/Look_star/article/details/88032821
只是我觉得他的描述还不够清晰,所以把自己理解的思路完善一下。
注:
不懂这个:
求一棵树之间两点最长的距离,即树的直径。
所以又搜了资料:
出自:https://www.cnblogs.com/tonghao/p/4740425.html
要用两次DFS求最长的距离。
而最远的点G-D,他们之间的距离即整棵树距离最长。
这里默认他们的权值为1,只是为了说明原理,具体搜索要根据路径的权值来定。
先给出所有的代码,然后对代码各部分进行详细解释。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
//动态链表
class Vertex{
ArrayList<Integer> V=new ArrayList();
}
class Edge{
ArrayList<Integer> E=new ArrayList();
}
public class Main {
final static int INF=0X3f3f3f3f;//10^9一般数都达不到这个,所以用它作为最大值
final static int maxn=100000;
static Vertex[] v=new Vertex[maxn+5];//V[i]存储与i相邻接的节点
static Edge[] e=new Edge[maxn+5];//e[i]存储与i邻接的边的距离
static boolean[] vis=new boolean[maxn+5];//防止重复访问
static int[] dis=new int[maxn+5];//存储原始结点到各结点的dfs距离
static void init(int n){//初始化
for(int i=0;i<n;i++){
v[i]=new Vertex();//为每个城市都创建一条链表,用来记录它所能邻接的城市
e[i]=new Edge();
}
}
static void dfs(int a){
int len=v[a].V.size();//与a相邻接的城市有几个
vis[a]=true;//a城市已经访问
for(int i=0;i<len;i++){//遍历城市
int j=v[a].V.get(i);//依次获取a邻接的几个城市
if(!vis[j]&&e[a].E.get(i)!=INF){
vis[j]=true;
dis[j]=dis[a]+e[a].E.get(i);
dfs(j);
vis[j]=false;//回溯
}
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
init(n);
for(int i=0;i<n-1;i++){
int a=sc.nextInt()-1;
int b=sc.nextInt()-1;
int c=sc.nextInt();
v[a].V.add(b);//a城市可以到b,所以,在他的链表里添加b
e[a].E.add(c);//用e记录对应的a-b的距离
v[b].V.add(a);//反之b可以到a
e[b].E.add(c);//用e记录对应的b-a的距离
}
//此类包含用来操作数组(比如排序和搜索)的各种方法
//将制定的false,INF分配给对应数组中的每个元素,相当于for初始操作的简化
Arrays.fill(vis,false);
Arrays.fill(dis,INF);
dis[0]=0;
dfs(0);//第一次遍历 求得某个城市到最远的城市的最大距离是多少,并用dis[]来记录 比如dis[1]=67;
long max=-1;
int temp=-1;
for(int i=0;i<n;i++){
if(dis[i]>max){
max=dis[i];
temp=i;
}
}
Arrays.fill(vis, false);
Arrays.fill(dis, INF);
dis[temp]=0;
dfs(temp);//第二次遍历 求b与?距离最远
long ans=-1;//防止越界
for(int i=0;i<n;i++){
if(dis[i]>ans){
ans=dis[i];
temp=i;
}
}
ans=ans*(ans+21)/2;
System.out.println(ans);
sc.close();
}
}
自定义两个类,分别构造了动态链表。
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
然后进行最后的计算就可以得出所花费的钱了。
好像代码里的注解会有些错误,因为代码里的注释不是最后的理解,有错好像没更改过来?
有点奇怪的是两次提交一个正确一个错误,中间好像没怎么修改啊,出现两个结果我还是有些一头雾水。
这个代码是之前的,如果运行错误,可找原文的代码,配上我写的注释一起看。