用Java写数据结构作业——7-2 Dijkstra算法(模板) (30分)

简介: 用Java写数据结构作业——7-2 Dijkstra算法(模板) (30分)

7-2 Dijkstra算法(模板) (30分)


给一个n(1 ≤ n ≤ 2500) 个点 m(1 ≤ m ≤ 6200) 条边的无向图,求 s 到 t 的最短路。

输入格式:

第一行四个由空格隔开的整数 n、m、s、t。

之后的 m 行,每行三个正整数 si、ti、wi(1≤wi≤109),表示一条从si 到 ti 长度为 wi 的边。

输出格式:

一个整数,表示从s 到t 的最短路径长度。数据保证至少存在一条道路。

输入样例:

7 11 5 4

2 4 2

1 4 3

7 2 2

3 4 3

5 7 5

7 3 3

6 1 1

6 3 4

2 4 3

5 6 3

7 2 1


输出样例:

7


注意:

两个顶点之间可能存在多条直接相连的道路。


思路

纵观此题,要注意的点有两个——一是两个顶点之间可能存在多条直接相连的道路;二是数据保证至少存在一条道路。这意味此图必是稠密图,每两个顶点之间都有一条及以上的道路。据此我们可以用矩阵来存储此图,不过与先前不同的是矩阵里的每个元素应是我们自己定义的一个类,但是此题只需算出最短路径,那么这题我们路径只需保留最短的即可。


程序框架设计

1.array矩阵表示图,num结点数量,edge边数,maxInt常量表示无穷大,distance矩阵记录各个点之间的最短距离,s起点,t终点

2.initialize方法初始化图

3.私有方法createEdge(int a,int b)方法 建立一条边,把最短的一条边记录

4.dijkstra()方法

5. findMinDistance(boolean[] collected) 返回未被收录顶点中dist最小者的下标

6.find(int t)输出打印到t点的最短距离


import java.util.*;
public class Main {
    //一个常量100000001表示无穷大
    final static int MaxInt=100000001;
    //节点个数
    static int num=0;
    //边数
    static int edge=0;
    //二维矩阵
    static int[][] array;
    static int[] distance;
    static int[] path;
    //起点
    static int s;
    //终点
    static int t;
    //建图模块
    public static void main(String[] args) {
        //初始化
        initialize();
        //调用dijkstra算法
        Dijkstra();
        //输出到t点的最短距离
        find(t);
    }
    public static void initialize(){
        //创建一个文本扫描器检测键盘输入
        Scanner scanner=new Scanner(System.in);
        num=scanner.nextInt();
        edge=scanner.nextInt();
        s= scanner.nextInt();
        t= scanner.nextInt();
        //注意这个下标并不是结点值,下标减一才是!!!
        array=new int[num][num];
        //初始化图中值
        for (int i=0;i<num;i++){
            for (int j=0;j<num;j++){
                array[i][j]=MaxInt;
            }
        }
        for (int i=0;i<edge;i++){
            creatEdge(scanner.nextInt(),scanner.nextInt(),scanner.nextInt());
        }
        //初始化path和distance数组
        path=new int[num];
        distance=new int[num];
    }
    //建立一条边,把小的一条边存储
    private static void creatEdge(int a,int b,int length){
        if (array[a-1][b-1]>length){
            array[a-1][b-1]=length;
            array[b-1][a-1]=length;
        }
    }
    private static boolean Dijkstra()
    {
        //记录该点是否访问过
        boolean collected[]=new boolean[num];
        /* 初始化:此处默认邻接矩阵中不存在的边用MaxInt表示 */
        for ( int i=0; i<num; i++ ) {
            distance[i] = array[i][s-1];
            if ( distance[i]<MaxInt )
                path[i] = s-1;
            else
                path[i] = -1;
            collected[i] = false;
        }
        /* 先将起点收入集合 */
        distance[s-1] = 0;
        collected[s-1] = true;
        while (true) {
            // temp = 未被收录顶点中dist最小者的下标
            int temp= findMinDistance(collected );
            if ( temp==-1 ) /* 若这样的temp不存在 */
                break;      /* 算法结束 */
            collected[temp] = true;  /* 收录temp */
            for( int i=0; i<num; i++ ) /* 对图中的每个顶点i+1 */
                /* 若i是temp的邻接点并且未被收录 */
                if ( collected[i]==false && array[temp][i]<MaxInt ) {
                    if (array[temp][i]<0 ) /* 若有负边 */
                        return false; /* 不能正确解决,返回错误标记 */
                    /* 若收录temp使得distance[i]变小 */
                    if ( distance[temp]+array[temp][i]< distance[i] ) {
                        distance[i] = distance[temp]+array[temp][i]; /* 更新distance[i] */
                        path[i] = temp; /* 更新s到i的路径 */
                    }
                }
        } /* while结束*/
        return true; /* 算法执行完毕,返回正确标记 */
    }
    //返回未被收录顶点中dist最小者的下标
    private static int findMinDistance(boolean[] collected){
        int min =MaxInt;
        int iMin=-1;
        for (int i=0;i<num;i++){
            if (min>distance[i]&&!collected[i]){
                min=distance[i];
                iMin=i;
            }
        }
        return iMin;
    }
    //输出打印到t点的最短距离
    private static void find(int t){
        System.out.println(distance[t-1]);
    }
}
相关文章
|
16天前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
2月前
|
机器学习/深度学习 负载均衡 算法
【柔性作业车间调度】基于四种多目标优化算法(NSOOA、NSPSO、NSDBO、NSCOA)求解柔性作业车间调度问题FJSP研究(Matlab代码实现)
【柔性作业车间调度】基于四种多目标优化算法(NSOOA、NSPSO、NSDBO、NSCOA)求解柔性作业车间调度问题FJSP研究(Matlab代码实现)
137 0
|
2月前
|
机器学习/深度学习 算法 Java
基于灰狼优化算法(GWO)解决柔性作业车间调度问题(Matlab代码实现)
基于灰狼优化算法(GWO)解决柔性作业车间调度问题(Matlab代码实现)
147 1
|
2月前
|
供应链 算法 Java
【柔性作业车间调度问题FJSP】基于非支配排序的多目标小龙虾优化算法求解柔性作业车间调度问题FJSP研究(Matlab代码实现)
【柔性作业车间调度问题FJSP】基于非支配排序的多目标小龙虾优化算法求解柔性作业车间调度问题FJSP研究(Matlab代码实现)
|
2月前
|
供应链 算法 调度
基于非支配吸血水蛭优化算法 (NSBSLO)求解多目标柔性作业车间调度问题(FJSP)研究(Matlab代码实现)
基于非支配吸血水蛭优化算法 (NSBSLO)求解多目标柔性作业车间调度问题(FJSP)研究(Matlab代码实现)
|
4月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
100 1
|
4月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
115 0
|
5月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
225 3
|
6月前
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
246 0
|
6月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!