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

af99d1b400a66922d17c11cd14329e83.png

657c1eeaca76315267531c611d45ddaa.png

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

https://blog.csdn.net/Look_star/article/details/88032821

只是我觉得他的描述还不够清晰,所以把自己理解的思路完善一下。

注:

dfa69d8fe59af03314f090d7458ca560.png

不懂这个:

求一棵树之间两点最长的距离,即树的直径。

所以又搜了资料:

931b3838adc45df3aa4b770b6539ad05.png

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

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

2d6cab5e32246c3d8466edd908d73297.png

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

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

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

1 importjava.util.ArrayList;2 importjava.util.Arrays;3 importjava.util.Scanner;4

5 //动态链表

6 classVertex{7 ArrayList V=newArrayList();8 }9 classEdge{10 ArrayList E=newArrayList();11 }12

13 public classMain {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

24 e[i]=newEdge();25 }26 }27

28 static void dfs(inta){29 int len=v[a].V.size();//与a相邻接的城市有几个

30 vis[a]=true;//a城市已经访问

31 for(int i=0;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 voidmain(String[] args) {43 Scanner sc=newScanner(System.in);44 int n=sc.nextInt();45

46 init(n);47

48 for(int i=0;i

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;imax){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;ians){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 }

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

a211aebe03849ab426e325f9dddc4534.png

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

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

93221e41df72d3eb5757c7c5434e5b71.png

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

de467cc3e1224e8ce4dfb4f53c3414fa.png

看main方法中:

DFS深度优先搜索:

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

b09800d7291b09aea869225c37146aeb.png

79e5f847283a35f03c1ea16681ab36ed.png

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

72ebac4b31e51900256d7e1dc511bf3b.png

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

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

1ce22f8514edaca7b6b1f066b617dfe9.png

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

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

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

151173260ba92e936699bf5748396723.png

有点奇怪的是两次提交一个正确一个错误,中间好像没怎么修改啊,出现两个结果我还是有些一头雾水。

这个代码是之前的,如果运行错误,可找原文的代码,配上我写的注释一起看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值