当前位置: 首页 > news >正文

图论------迪杰斯特拉(Dijkstra)算法求单源最短路径。

编程要求


在图的应用中,有一个很重要的需求:我们需要知道从某一个点开始,到其他所有点的最短路径。这其中,Dijkstra 算法是典型的最短路径算法。

本关的编程任务是补全右侧代码片段中 Begin 至 End 中间的代码,实现 Dijkstra 算法求单源最短路径,具体要求如下:

补全代码 int[] Paths(int source) 方法,实现 Dijkstra 算法;

输出源点 source 到其他各个定点的距离,如果不可达,则距离输出 INF。

测试举例
测试过程:

平台将创建用户补全后的ShortestPath类的对象;

调用对象的addEdge(int u, int v, int w)方法,添加边和边的权重信息,构建图G;

调用对象的Paths(int source)方法执行Dijkstra算法,求最短路径,并输出返回的最短路径,这里源点设置为1;

接着根据程序的输出判断程序是否正确。

以下是测试样例:

测试输入:

5 7
1 2 8
1 3 1
1 4 2
3 4 2
2 4 3
3 5 3
4 5 3
(5 和 7 分别表示顶点数和边数)

预期输出:

0 5 1 2 4 

思路解析:

        求单源最短路径就是求一个点到除它以外所有点的最短距离,首先我们还是用邻接矩阵来储存图的信息。以测试输入为例,示意图如下。


        既然是求1的单源最短路径,那我们就定义一个数组dic[n+1],将dic初始化存储从1到所有点的直接距离。比如dic[1]到dic[5]分别是【0,8,1,2,99999999】,因为1无法直接到5,所以初始化为99999999。

        然后找出dic里面1到2-n之间的最短距离,发现是dic[3] = 1,然后找1通过3能到达的地方,发现能到达4和5,如果1通过3到达4的话,得出dic[4] = 2 < dic[3]+arr[3][4] = 3,无法使到四的路程更短,所以不改变dic[4]的值,但是我们发现到达5,即dic[5] = 99999999>dic[3]+arr[3][5] = 4,能使1到5距离缩短,于是改变dic[5]的值。这样我们就得到能通过3进行优化一轮路径,学术名叫做松弛。

        


        我们知道,如果已经通过3实现了一轮优化,那么我们将进一步缩短路程的话,是不能走回头路的,因为如果再次经过3的话没有意义,所以最短路没有重复路径。

        那么我们就要定义一个数组来存储已经作为转点进行一轮松弛的点,我们可以定义book[n+1]来存储。将作为转点的点比如3,用book[3] = 1,表示已经使用过。

        之后便是重复步骤,找除去dic[3]以外的最小值,也就是dic[4],继续进行一轮松弛,将4这个点用book[4] = 1,表示已经使用过。

        之后的图大家可以自己试着来画出。

具体代码:

#include<stdio.h>

int main(void)

{

    int arr[100][100] = { 0 };

    int dic[100];

    int book[100] = { 0 };

    int m, n, a, b, c, u, v;

    int inf = 99999999;

    scanf("%d%d", &n, &m);

    for (int i = 1; i <= n; i++)

        for (int j = 1; j <= n; j++)

            if (i == j)

                arr[i][j] = 0;

            else

                arr[i][j] = inf;

    for (int i = 1; i <= m; i++)

    {

        scanf("%d%d%d", &a, &b, &c);

        arr[a][b] = c;

        arr[b][a] = c;

    }//无向图初始化。

    for (int i = 1; i <= n; i++)

        dic[i] = arr[1][i];//初始化dic数组


 

    for (int i = 1; i <= n - 1; i++)//最多要进行n-1轮松弛,i值不会使用,仅仅表示循环多少轮。

    {

        int min = inf;

        for (int j = 2; j <= n; j++)

        {

            if (book[j] == 0 && dic[j] < min)

            {

                min = dic[j];

                u = j;

            }

        }//找出从1到任意数字的最短值。

        book[u] = 1;//将该位置提前存储,表示已经使用过。

        for (v = 2; v <= n; v++)//优化1通过u到所有点的路径。

        {

            if (arr[u][v] < inf)//如果u到v没有通路,也就没办法优化。

            {

                if (dic[v] > dic[u] + arr[u][v])

                    dic[v] = dic[u] + arr[u][v];//优化赋值过程。

            }

        }

    }

    for (int i = 1; i <= n; i++)

        printf("%d ", dic[i]);//打印结果。

    return 0;

}

注意:

        实际上迪杰斯特拉算法可以看作是贪心算法,通过每一步的最优解组合成全局最优解,感兴趣的同学们可以去网上查找关于贪心算法的知识,这种类型的题目我们以后也会分享。

http://www.lryc.cn/news/423611.html

相关文章:

  • 河工院首届工业设计大赛程序组(挑战赛)题解
  • 文件上传漏洞(二,靶场搭建及漏洞利用)
  • 大厂面试题分享第二期
  • zabbix安装
  • SpringBoot集成日志框架
  • CSS笔记总结(Xmind格式):第三天
  • WordPress原创插件:Keyword-ranking-seo 1.0 关键词排名插件 有利于seo
  • Docker Swarm 管理
  • 跨平台、多格式、云同步,Koodo Reader背后的技术亮点
  • 【Story】如何高效记录并整理编程学习笔记?
  • jenkins 安装以及自动构建maven项目并且运行
  • Java虚拟机:虚拟机介绍
  • 硬件面试经典 100 题(31~40 题)CRE4
  • ReactNative笔记(自用)
  • 嵌入式八股-面试30题(20240812)
  • 单一职责原则(SRP)
  • 骨传导耳机怎么选?分享五款资深用户都说好的骨传导耳机!
  • 【计算机网络——分组延时,丢失,吞吐量】
  • 使用1panel 申请证书配置雷池站点
  • 4章7节:用R做数据重塑,数据去重和数据的匹配
  • 大数据面试SQL(七):累加刚好超过各省GDP40%的地市名称
  • 建议收藏!这4款设计师常用的素材管理软件,助你工作效率翻倍!
  • 用于NLP领域的排序模型最佳实践
  • 域名未备案的支付平台遭遇大攻击怎么办
  • 【NI-DAQmx入门】LabVIEW数据采集基础应用程序框架
  • 海山数据库(He3DB)源码详解:CommitTransaction函数源码详解
  • 【网络】传输层TCP协议的报头和传输机制
  • 【活动报名】打造编程学习“知识宝库”:高效笔记记录与整理指南
  • 使用Arduino IDE生成带有bootloader的烧录文件
  • 搭建高可用OpenStack(Queen版)集群(九)之部署nova计算节点