2019蓝桥杯Java第十题大学生B组——最短路径思想
题目:
代码:
package priv.tzk.lanqiao.ten; import java.io.IOException; import java.util.Scanner; public class Main { public static void main(String[] args) { //System.out.println("输入测量点的个数"); Scanner scN = new Scanner(System.in); int n=scN.nextInt();//坐标个数 int d;//最大长度 int array[][] = new int[n][3];//保存输入的坐标 double [][]Graph = new double[n][n];//保存各个点之间的距离 //将坐标存入二维数组 for(int i=0;i<n;i++) { //System.out.println("输入第"+i+"个测量点的坐标"); Scanner sc = new Scanner(System.in); array[i][0]=sc.nextInt(); array[i][1]=sc.nextInt(); array[i][2]=sc.nextInt(); } //System.out.println("输入两点之间最大距离"); Scanner scD = new Scanner(System.in); d=scD.nextInt(); //求各个点之间的距离,存入二维数组中,得到图 for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { double l=countLong(array[i][0],array[j][0],array[i][1],array[j][1],array[i][2],array[j][2]); if(l<=d) { Graph[i][j]=l; }else { Graph[i][j]=1000000; } } } //寻找终点,高度最低 int []f=new int[n];//记录终点 double []fl=new double[n];//保存不同终点的最大路径 int min=array[0][2]; //寻找最低点,终点不唯一 for(int i=0;i<n;i++) { if(min>array[i][2]) { min=array[i][2]; f[i]=1;//记录最低点的位置 } } //求两点间最大路径 for(int i=0;i<n;i++) { if(f[i]==1) { int vs=0;//题目已知第一个为起点 int vf=i;//终点 try { double re=dijkstra(vs,vf,Graph); fl[i]=re; } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } for(int i=0;i<n;i++) { double max=fl[0]; if(f[i]==1) { if(max<fl[i]) { max=fl[i]; } } System.out.println("最大路径为"+max); } } /* * 求两点距离 */ public static double countLong(int x1,int x2,int y1,int y2,int z1,int z2) { double count=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2); double re=Math.sqrt(count); return re; } /* * Dijkstra最短路径。 * 即图中"节点vs"到其它各个节点的最短路径。 * @param vs 起始节点 * @param Graph 图 * 将最短路径上的顶点,距离存入泛型集合list,返回 * 注意整型用Integer不能用int */ public static double dijkstra(int vs,int vf,double Graph[][]) throws IOException { double re=0; int NUM = Graph[0].length; int[] prenode = new int[NUM];//前驱节点数组 double[] path = new double[NUM];//最短距离数组 boolean[] flag = new boolean[NUM];// 该节点是否已经找到最短路径 int vnear = 0;//距离vs最近的节点 //初始化 for (int i = 0; i <path.length; i++) { prenode[i] = i; path[i] = Graph[vs][i];//顶点i的最短路径为顶点vs到i的权 flag[i] = false; } flag[vs] = true;//vs自身初始化 //遍历 Graph.length-1次,找出每个顶点的最短路径 for (int v = 1; v < Graph.length; v++) { double min = 100000; for (int j = 0; j < Graph.length; j++) { if (!flag[j] && path[j] > min) { min = path[j]; vnear = j; } } flag[vnear] = true; for (int k = 0; k < Graph.length; k++) { if (!flag[k] && (min + Graph[vnear][k]) > path[k]) { prenode[k] = vnear; path[k] = min + Graph[vnear][k]; } } } //依次保存前驱,输出 for(int i=0;i<10&&prenode[vf]!=vs;i++) {//i范围根据自己表的情况 re=Graph[prenode[vf]][vf]+re; vf=prenode[vf]; } return re; } }
运行结果:
注:结果没有验证对错,如果有错,请大神评论指出