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
然后进行最后的计算就可以得出所花费的钱了。
好像代码里的注解会有些错误,因为代码里的注释不是最后的理解,有错好像没更改过来?
标签:maxn,int,ans,蓝桥,static,new,旅费,PREV,dis 来源: https://www.cnblogs.com/xly1997/p/10585038.html