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

     运行结果:

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

  • 相关阅读:
    如何删除windows服务zz 重新安装PostgreSQL时删除上次遗留service的方法
    如何配置OGRE 1.7.0+CEGUI 0.7.1
    [原]一个由memset引发的知识点
    ArcGis测距问题
    自己动手,制作.net35离线安装包
    TTS语音合成
    Acess字段名用到与系统冲突的特殊名时的处理
    程序运行长期等待时显示等待动画
    修改Windows 2003 SOCKET端口数量默认5000限制
    服务器上发布的网站应用80端口时内网可以访问,外网不能访问
  • 原文地址:https://www.cnblogs.com/sengzhao666/p/11920419.html
Copyright © 2020-2023  润新知