Dijkstra 算法解决的是带权重的有向图上单源最短路径问题,该算法要求所有边的权重都为非负值。该算法的时间复杂度是O(N2),相比于处理无负权的图时,比Bellmad-Ford算法效率更高。

算法描述:

首先引用《算法导论》中的一段比较官方的话,如果可以看懂,那下一部分就可以跳过了:

“Dijkstra算法在运行过程中维持的关键信息是一组结点集合S。从源结点s到该集合中每个结点之间的最短路径已经被找到。算法重复从结点集 V - S 中算则最短路径估计的最小的结点 u ,将 u 加入到集合S,然后对所有从 u 出发的边进行松弛。” 所谓松弛操作,简单的说就是更新两点间的最短距离。

不是很好理解对吧,那么下面的描述是更容易理解的一种描述:

设起始点为s,dis[v]表示s点到v点的最短路径,pre[v]是v的前驱结点,用来输出路径。

1、初始化:dis[v]=∞(v≠s) dis[s]=0,pre[s]=0;

2、for(i=1;i<=n;i++)

(1)在没有被访问过的点中,即上述的V - S集合,找到一个点 u 使得dis[u]是最小的。

(2)标记 u 为已确定的最短路径。

(3)for(每个与 u 相连且没有确定过最短距离的点 v)

if(dis[u]+m[u][v]<dis[v]){

dis[v]=dis[u]+m[u][v];

pre[v]=u;

}

3、结束:结果dis[v]就是s到v的最短距离。

算法理解:

其中自以为有几点理解需要说明:

1、为什么用到中间点?

2、取s到中间点的距离时采用什么策略?

第一个问题,从起点到另一个点的最短路径至少会经历一个中间点,所以我们要求出经过这个中间的到另一个点的路径,就要先求出起点到中间点的最短路径。

第二个问题,其实这里采用的是一中贪心的策略。当然这个策略可以被严格证明是正确的,但是我也一知半解,只知道是可以被证明的,在这里也就不浪费时间了。(详细可以参考《算法导论》)

最后,解释一下为什么有负权边的时候不可以:

连接矩阵如下(图可以自己在旁边画一下):

1 2 3

1 \ 2 1

2 2 \ -4

3 1 -4 \

那么第一次标记的点就为3并且把dis[3]记为1,但实际上dis[3]应该时-2,因此就会出现错误。

最后附上一段不那么标准的代码:

 #include<stdio.h>
#include<stdlib.h>
int m[][],e,dist[],n,b[],pre[],dist[];
void dij(int s){
b[s]=;
int i,j;
for(i=;i<=n;i++)
dist[i]=m[s][i];
dist[s]=;
pre[s]=; for(i=;i<=n;i++){
int min=,k=;
for(j=;j<=n;j++)
if(b[j]!= && dist[j]<min)
{min=dist[j];k=j;}
b[k]=;
for(j=;j<=n;j++)
if(min+m[k][j]<dist[j]&&b[j]!=)
{
dist[j]=min+m[k][j];
pre[j]=i;
}
}
for(i=;i<=n;i++)
if(i!=s)
printf("%d ",dist[i]);
}
int main(){
int i,j;
scanf("%d%d",&n,&e);
memset(b,,sizeof(b));
memset(m,,sizeof(m));
for(i=;i<=e;i++){
int x,y;
scanf("%d%d",&x,&y);
scanf("%d",&m[x][y]);
}
int w;
scanf("%d",&w);
dij(w);
system("pause");
return ;
}

最短路径算法 2.Dijkstra算法的更多相关文章

  1. 最短路径算法(Dijkstra算法、Floyd-Warshall算法)

    最短路径算法具体的形式包括: 确定起点的最短路径问题:即已知起始结点,求最短路径的问题.适合使用Dijkstra算法. 确定终点的最短路径问题:即已知终结结点,求最短路径的问题.在无向图中,该问题与确 ...

  2. C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)

    1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...

  3. 最短路径问题的Dijkstra算法

      问题 最短路径问题的Dijkstra算法 是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出.迪科斯彻算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法终于得到一个最短路径树>    ...

  4. 【算法】Dijkstra算法(单源最短路径问题)(路径还原) 邻接矩阵和邻接表实现

    Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...

  5. 单源最短路径问题2 (Dijkstra算法)

    用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...

  6. 数据结构与算法系列研究七——图、prim算法、dijkstra算法

    图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...

  7. Prim算法、Kruskal算法、Dijkstra算法

    无向加权图 1.生成树(minimum spanning trees) 图的生成树是它一棵含有所有顶点的无环联通子图 最小生成树:生成树中权值和最小的(所有边的权值之和) Prim算法.Kruskal ...

  8. 算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法

    一.名称 动态规划法应用 二.目的 1.贪婪技术的基本思想: 2.学会运用贪婪技术解决实际设计应用中碰到的问题. 三.要求 1.实现基于贪婪技术思想的Prim算法: 2.实现基于贪婪技术思想的Dijk ...

  9. 最短路径算法之Dijkstra算法(java实现)

    前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知 ...

  10. 图中最短路径算法(Dijkstra算法)(转)

    1.Dijkstra 1)      适用条件&范围: a)   单源最短路径(从源点s到其它所有顶点v); b)   有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E ...

随机推荐

  1. Bootstrap后台管理模板调研

    Bootstrap后台管理模板调研 SB Admin 2(推荐) SB Admin 2是一款开源的基于Bootstrap搭建的后台管理模板,简约,易用.没有复杂的组件和花炫的设计,很质朴,但较为美观. ...

  2. 环境变量PATH超长问题[转]

    症状回放: 最近安装一个Delphi的控件,结果,在安装之后启动Delphi时出现了找不到相关文件的错误.一开始以为是Delphi内的Library路径没有添加,查看,一切正常.再次启动Delphi, ...

  3. Qt socket制作一个简单的文件传输系统

    服务器 用qt designer设计出服务器界面: 上代码: Server.pro #------------------------------------------------- # # Pro ...

  4. 在已有软件加壳保护 下实现 Inline hook

    如写的不好请见谅,本人水平有限. 个人简历及水平:. http://www.cnblogs.com/hackdragon/p/3662599.html 正常情况: 接到一个项目实现对屏幕输出内容的获取 ...

  5. wireshark抓取本地回环数据包

      linux环境下,用tcpdump,可以用-i lo参数抓取环回接口的包.如果服务端和客户端安装在同一台机器上,调试时是很方便的.linux版的wireshark,选取网卡的菜单里也有lo选项,也 ...

  6. 【洛谷5287】[HNOI2019] JOJO(主席树优化KMP)

    点此看题面 大致题意: 每次往一个字符串末尾加上\(x\)个字符\(c\),或者回到某一历史版本,求\(KMP\)的\(\sum Next_i\). 问题转化 考虑到可以离线. 于是,我们就可以用一个 ...

  7. 【洛谷5294】[HNOI2019] 序列(主席树维护单调栈+二分)

    点此看题面 大致题意: 给你一个长度为\(n\)的序列\(A\),每次询问修改一个元素(只对当前询问有效),然后让你找到一个不下降序列\(B\),使得这两个序列相应位置之差的平方和最小,并输出这个最小 ...

  8. 12java基础继承

    26.定义类Human,具有若干属性和功能:定义其子类Man.Woman: 在主类Test中分别创建子类.父类和上转型对象,并测试其特性.   package com.hry.test; public ...

  9. Python 学习笔记(四)数字(二)

    Python Python2 中除法的问题 >>> 3 / 6 0 >>> 3.0 / 6 0.5 >>> 3.0 / 6.0 0.5 >& ...

  10. center os 文件读写权限

    五.使用chmod和数字改变文件或目录的访问权限文件和目录的权限表示,是用rwx这三个字符来代表所有者.用户组和其他用户的权限.有时候,字符似乎过于麻烦,因此还有另外一种方法是以数字来表示权限,而且仅 ...