• 最短路径(图中两点间最短路径)


    求解城市之间的最短距离是一个非常实际的问题,其大意如下:

    某地区由n个城市,如何选择路线使某个城市到某个指定城市的的距离最短?

    注意:这里需要求解的最短路径指的是两个城市之间的最短距离,而不是所有城市之间最短总距离。

    1.最短路径算法

        //最短路径算法
        static void distMin(GraphMatrix GM,int vend){    //vend为结束点
            int[] weight=new int[GraphMatrix.MaxNum];        //某终止点到各顶点的最短路径长度
            int i,j,k,min;
            vend--;
            for(i=0;i<GM.VertexNum;i++){        //初始化weight数组
                weight[i]=GM.EdgeWeight[vend][i];
            }
            for(i=0;i<GM.VertexNum;i++){        //初始化path数组
                if(weight[i]<MaxValue&&weight[i]>0){    //有效权值
                    path[i]=vend;
                }
            }
            for(i=0;i<GM.VertexNum;i++){        //初始化tmpvertex数组
                tmpvertex[i]=0;            //初始化顶点集合为空
            }
            tmpvertex[vend]=1;        //选入顶点vend
            weight[vend]=0;
            for(i=0;i<GM.VertexNum;i++){        //查找未用顶点的最小权值
                min=MaxValue;
                k=vend;
                for(j=0;j<GM.VertexNum;j++){
                    if(tmpvertex[j]==0&&weight[j]<min){
                        min=weight[j];
                        k=j;
                    }
                }
                tmpvertex[k]=1;            //将顶点k选入
                for(j=0;j<GM.VertexNum;j++){        //以顶点k为中间点,重新计算权值
                    if(tmpvertex[j]==0&&weight[k]+GM.EdgeWeight[k][j]<weight[j]){
                        weight[j]=weight[k]+GM.EdgeWeight[k][j];
                        path[j]=k;
                    }
                }
            }
        }

    2.完整的程序代码示例

    package com.cn.datastruct;
    
    import java.util.Scanner;
    
    //最短路径求解
    public class DistMin {
        static class GraphMatrix{
            static final int MaxNum=20;
            char[] Vertex=new char[MaxNum];  //保存顶点信息(序号或字母)
            int GType;    //图的类型(0:无向图,1:有向图)
            int VertexNum;        //顶点的数量
            int EdgeNum;        //边的数量
            int[][] EdgeWeight=new int[MaxNum][MaxNum];        //保存边的权
            int[] isTrav=new int[MaxNum];        //遍历标志
        }
        
        static final int MaxValue=65535;    //最大值(可设为一个最大整数)
        static int[] path=new int[GraphMatrix.MaxNum];    //两点经过的顶点集合的数组
        static int[] tmpvertex=new int[GraphMatrix.MaxNum];  //最短路径的起始点集合
        static Scanner input=new Scanner(System.in);
        
        //创建邻接矩阵图
        static void CreateGraph(GraphMatrix GM){
            int i,j,k;
            int weight;     //
            char EstartV,EendV;        //边的起始顶点
            System.out.printf("输入图中各顶点信息
    ");
            for(i=0;i<GM.VertexNum;i++){        //输入顶点
                System.out.printf("第%d个顶点:", i+1);
                GM.Vertex[i]=(input.next().toCharArray())[0];  //保存到各顶点的数组元素中
            }
            System.out.printf("输入构成各边的顶点及权值:
    ");
            for(k=0;k<GM.EdgeNum;k++){            //输入边的信息
                System.out.printf("第%d条边:", k+1);
                EstartV=input.next().charAt(0);
                EendV=input.next().charAt(0);
                weight=input.nextInt();
                for(i=0;EstartV!=GM.Vertex[i];i++);      //在已有顶点中查找始点
                for(j=0;EendV!=GM.Vertex[j];j++);        //在已有的顶点中查找终点
                GM.EdgeWeight[i][j]=weight;          //对应位置保存权值,表示有一条边
                if(GM.GType==0){        //若是无向图
                    GM.EdgeWeight[j][i]=weight;        //在对角位置保存权值
                }
            }
        }
    
        // 清空矩阵
        static void ClearGraph(GraphMatrix GM) {
            int i, j;
            for (i = 0; i < GM.VertexNum; i++) {
                for (j = 0; j < GM.VertexNum; j++) {
                    GM.EdgeWeight[i][j] = MaxValue; // 设置矩阵中各元素的值为MaxValue
                }
            }
        }
    
        // 输出邻接矩阵
        static void OutGraph(GraphMatrix GM) {
            int i, j;
            for (j = 0; j < GM.VertexNum; j++) {
                System.out.printf("	%c", GM.Vertex[j]); // 在第一行输出顶点信息
            }
            System.out.println();
            for (i = 0; i < GM.VertexNum; i++) {
                System.out.printf("%c", GM.Vertex[i]);
                for (j = 0; j < GM.VertexNum; j++) {
                    if (GM.EdgeWeight[i][j] == MaxValue) { // 若权值为最大值
                        System.out.printf("	Z"); // 以Z表示无穷大
                    } else {
                        System.out.printf("	%d", GM.EdgeWeight[i][j]); // 输出边的权值
                    }
                }
                System.out.println();
            }
        }
        
        //最短路径算法
        static void distMin(GraphMatrix GM,int vend){    //vend为结束点
            int[] weight=new int[GraphMatrix.MaxNum];        //某终止点到各顶点的最短路径长度
            int i,j,k,min;
            vend--;
            for(i=0;i<GM.VertexNum;i++){        //初始化weight数组
                weight[i]=GM.EdgeWeight[vend][i];
            }
            for(i=0;i<GM.VertexNum;i++){        //初始化path数组
                if(weight[i]<MaxValue&&weight[i]>0){    //有效权值
                    path[i]=vend;
                }
            }
            for(i=0;i<GM.VertexNum;i++){        //初始化tmpvertex数组
                tmpvertex[i]=0;            //初始化顶点集合为空
            }
            tmpvertex[vend]=1;        //选入顶点vend
            weight[vend]=0;
            for(i=0;i<GM.VertexNum;i++){        //查找未用顶点的最小权值
                min=MaxValue;
                k=vend;
                for(j=0;j<GM.VertexNum;j++){
                    if(tmpvertex[j]==0&&weight[j]<min){
                        min=weight[j];
                        k=j;
                    }
                }
                tmpvertex[k]=1;            //将顶点k选入
                for(j=0;j<GM.VertexNum;j++){        //以顶点k为中间点,重新计算权值
                    if(tmpvertex[j]==0&&weight[k]+GM.EdgeWeight[k][j]<weight[j]){
                        weight[j]=weight[k]+GM.EdgeWeight[k][j];
                        path[j]=k;
                    }
                }
            }
        }
        
        public static void main(String[] args) {
            GraphMatrix GM=new GraphMatrix();   //定义保存邻接表结构的图
            String go;
            int vend;
            int i,k;
            System.out.println("求解最短路径问题!");
            do{
                System.out.print("请先输入生成图的类型:");
                GM.GType=input.nextInt();   //图的种类
                System.out.print("请输入图的顶点数量:");
                GM.VertexNum=input.nextInt();         //输入图中顶点数
                System.out.print("请输入图的边的数量:");
                GM.EdgeNum=input.nextInt();        //输入图中边数
                ClearGraph(GM);            //清空图
                CreateGraph(GM);        //生成邻接表结构的图
                
                System.out.print("
    请输入结束点:");
                vend=input.nextInt();
                
                distMin(GM,vend);
                vend--;
                System.out.printf("
    个顶点到达顶点%c的最短路径分别为(起始点-结束点):
    ",GM.Vertex[vend]);
                for(i=0;i<GM.VertexNum;i++){        //输出结果
                    if(tmpvertex[i]==1){
                        k=i;
                        while(k!=vend){
                            System.out.printf("顶点%c-", GM.Vertex[k]);
                            k=path[k];
                        }
                        System.out.printf("顶点%c
    ", GM.Vertex[k]);
                    }else{
                        System.out.printf("%c-%c:无路径
    ", GM.Vertex[i],GM.Vertex[vend]);
                    }
                }
                System.out.println("
    继续玩吗(y/n)?");
                go=input.next();
            }while(go.equalsIgnoreCase("y"));
            System.out.println("游戏结束!");
        }
    
    }

    程序运行结果如下:

    求解最短路径问题!
    请先输入生成图的类型:0
    请输入图的顶点数量:5
    请输入图的边的数量:6
    输入图中各顶点信息
    第1个顶点:1
    第2个顶点:2
    第3个顶点:3
    第4个顶点:4
    第5个顶点:5
    输入构成各边的顶点及权值:
    第1条边:1 2 2
    第2条边:1 3 5
    第3条边:1 5 3
    第4条边:2 4 4
    第5条边:3 5 5
    第6条边:4 5 2
    
    请输入结束点:1
    
    个顶点到达顶点1的最短路径分别为(起始点-结束点):
    顶点1
    顶点2-顶点1
    顶点3-顶点1
    顶点4-顶点5-顶点1
    顶点5-顶点1
    
    继续玩吗(y/n)?
    n
    游戏结束!
  • 相关阅读:
    NOIP2016 愤怒的小鸟
    LCIS code force 10D
    UVA 1398
    uva1382 Distant Galaxy
    洛谷-3930(我在洛谷上也写了题解)
    HDU-1505 City Game
    导弹拦截n logn的算法(单调性)洛谷1020
    POJ 1182 食物链
    POJ
    1202. 交换字符串中的元素
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4507763.html
Copyright © 2020-2023  润新知