最短路算法1(Dijkstra算法)

迪杰斯特拉算法原理

一.迪杰斯特拉算法原理
运用贪心的思想来处理最短路问题,先从起点开始,遍历与起点有相连的边,然后更新相连点的权值(标记起点),再从与起点相连边中权值最小的点为新起点(就是这里用了贪心,该起点应没被标记过)重复以上操作n -1 次(看不懂很正常,看下下面的例子就大概懂了)。
二.关于迪杰斯特拉算法时间复杂度
本蒟蒻写的最朴素的版本没用优化 ,时间复杂度为O( V * E),据说是可以用堆优化。
三.举个栗子
我们要从城市a到城市d(共4个点 n = 4). 有4 条路径如下,问怎么走时间最短?
起 终 time
a - > b 1
b - > c 1
c - > d 1
a - > d 5
1.设置距离数组d[5],用于存放起点掉该编号点的最小距离,先初始化该数组的值为无穷大(inf)因为初始时到不了 ,然后把起点的d[a] 的距离变为0自己到自己不就0吗 再设置一个标记数组f[5] 初始化其成员值为0(表示没来过)
2. 我们先从起点(来到起点了 ,f[1] =0 标记一下)开始处理, 找a 能直接到的点,并更新到该点的最小时间再标记该点。
d[5] = 0 0 1 inf 5
f[5] =0 1 0 0 0
ps:城市下标从1开始,而数组下标是从0 开始的
3.从距离数组中找到距离最小且没有被标记的那个点为新起点,重复 2 操作n - 2次·

重复第1次
d[5] = 0 0 1 2 5
f[5] =0 1 1 0 0
重复第2次
d[5] =0 0 1 2 3
f[5] =0 0 1 1 0

迪杰斯特拉算法的代码分析

起始条件:给定起点o,终点p,以及各个边,边用邻接矩阵存。
刚开始假设从起点 o 到起点 o 的距离为0,到其他节点的距离为inf(无穷大),先从起点o遍历一遍 即设置距离数组的d[maxn], d[o] = 0, 其他数组元素的值为inf(无穷大)

    memset(d, inf, sizeof(d));
    d[1] = 0;//1为起点
    f[1] = 1;//标记起点, 放入走过的集合(不走第2次)
    for(int i = 1; i <= n; ++i)
    {
       d[i] = min(d[i], d[1] + a[1][i];
    }

1.遍历一遍距离数组d[maxn],找到最小权值的下标,并进行标记,防止这个点处理两次。

 int temp = 0, minn = inf;//temp记录d数组中最小距离的下标,minn记录最小权值
        for (int j = 1; j <= n -2; ++j) {
            if (d[j] < minn && f[j] == 0) {//当前权值较小,且没处理过
                temp = j;
                minn = d[j];
            }
        }
        f[temp] = 1;//进行标记

2.从起点 o 开始(标记起点 o ),找与相连的点,进行边的 ” 松弛“ 操作(即更新这点的权值, 变得更小 )。

     for (int j = 1; j <= n; ++j) {
            if (d[j] > d[temp] + a[temp][j])
            {
                d[j] = d[temp] + a[temp][j];
            }
        }

3.重复1,2步骤n - 2次

 for (int i = 1; i < n; ++i) {
 //步骤 1
        int temp = 0, minn = inf;
        for (int j = 1; j <= n; ++j) {
            if (d[j] < minn && f[j] == 0) {
                temp = j;
                minn = d[j];
            }
        }
        f[temp] = 1;
 //步骤 2
        for (int j = 1; j <= n; ++j) {
            if (d[j] > d[temp] + a[temp][j])
            {
                d[j] = d[temp] + a[temp][j];
            }
        }
    }

例题及应用

例题模板题
实验室有很多台计算机,由于每个人计算机的性能不同,导致计算机之间发送信息的速度不同,所以花费时间不同。
消息从第一台电脑发送到第二台电脑后,这两台电脑能再向其他电脑发送消息,就是一种类似二叉树的结构。
当然并不是真正的二叉树——我们的计算机有一些特殊的特性,我们应该加以利用。
我们的计算机允许同时向连接到它的任意数量的其他计算机发送消息。
然而,消息不一定同时到达目的地——这涉及到计算机配置。
一般来说,我们需要考虑到拓扑结构中每个计算机的时间成本,并相应地计划将消息传播所需的总时间降到最低。
涂爷需要经常给其他人发消息,她想要知道如果她发出一个消息,至少要等多久全部的人才可以都收到通知。
Input
第一行输入一个n,表示有多少台计算机(涂爷当然是一号机啦~)。
随后n-1行,以邻接矩阵的形式给出计算机(1~n)之间通讯需要的时间。
由于两台计算机相互通信时间相等,且计算机自己和自己不需要通信,所以只给出了矩阵的下三角。ps:x表示由于部分计算机之间存在特殊的磁场并不能通信。ps2:该题所有数据范围0~100。
Output
输出一行表示涂爷需要等待的时间。
Sample Input
5
50
30 5
100 20 50
10 x x 10
Sample Output
35
解题方法: 输入数据,设1为起点,n为终点,跑一遍Dijkstra , 然后输出。
应用
不仅可以计算两点之间的最短路,还能计算从起点出发到每个点的最短路,即单源最短路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值