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. 7.Zabbix 3.0 web监控

    请查看我的有道云笔记: http://note.youdao.com/noteshare?id=5f6b67f98a802fb831a83d810969c583&sub=B8D5267BDD5 ...

  2. oracle备份恢复

    1.oracle文件备份恢复 /etc/oraInst.loc /etc/oratab /home/oracle 家目录 /oracle 安装目录 /usr/local/bin/dbhome /usr ...

  3. Windows 系统 Unicode 文件名操作(新建、重命名、枚举、复制)全攻略

    常见的那些文件操作函数都不支持,于是为了达到目的,需要各种方法配合,应该是不如其他语言方便.我只是想看看Perl到底是否适合做这件事,于是折腾了一回. 文件的建立: 模块:Win32 Code: [全 ...

  4. 找出OData service出错根源的小技巧

    SAP的Fiori应用是通过OData和后台交互的.在使用Fiori应用时您可能会遇到这样的错误消息: 这个错误消息没有包含有助于partner或者客户定位问题根源的线索. 下面是如何在后台找出问题根 ...

  5. IOS CoreLocation框架的使用(用于地理定位)

    ●  在移动互联网时代,移动app能解决用户的很多生活琐事,比如 ●  导航:去任意陌生的地方 ●  周边:找餐馆.找酒店.找银行.找电影院 ●  在上述应用中,都用到了地图和定位功能,在iOS开发中 ...

  6. 报表技术之PDF格式报表生成 ----JasperResport

    JasperReport简介 JasperReport:java提供的一个类库,承上启下,读取IReport生成的xxx.jrxml文件,获取到pdf中需要显示的全部内容,然后底层调用IText相关的 ...

  7. Hibernate注解开发示例

    -------------------------------------------------------------------customer------------------------- ...

  8. express框架开发笔记

    1.express项目修改不重启 $ supervisor node bin/www 让supervisor监听模板文件的改动 $ supervisor --extensions html,css,j ...

  9. 【luogu P3373 线段树2】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3373 lazy标记两个,先乘后加 #include <iostream> #include &l ...

  10. javascript操作Date对象

    Date 对象用于处理日期和时间. 创建 Date 对象的语法: var myDate=new Date() Date 对象会自动把当前日期和时间保存为其初始值. 参数形式有以下5种: new Dat ...