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;
    }
}

 运行结果:

注:结果没有验证对错,如果有错,请大神评论指出

 

 

posted @ 2019-11-23 22:06  田智凯  阅读(308)  评论(0编辑  收藏  举报