Dijkstra算法

———————————
最后更新时间:2011.9.25
———————————
Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。

其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。

初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。

例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下表中。

Dijkstra算法的迭代过程:

主题好好理解上图!

以下是具体的实现(C/C++):

/***************************************
* About:    有向图的Dijkstra算法实现
* Author:   Tanky Woo
* Blog:     www.WuTianQi.com
***************************************/
 
#include <iostream>usingnamespace std;
 
constint maxnum =100;constint maxint =999999;
 
// 各数组都从下标1开始int dist[maxnum];// 表示当前点到源点的最短路径长度int prev[maxnum];// 记录当前点的前一个结点int c[maxnum][maxnum];// 记录图的两点间路径长度int n, line;// 图的结点数和路径数
 
// n -- n nodes// v -- the source node// dist[] -- the distance from the ith node to the source node// prev[] -- the previous node of the ith node// c[][] -- every two nodes' distancevoid Dijkstra(int n, int v, int*dist, int*prev, int c[maxnum][maxnum]){bool s[maxnum];// 判断是否已存入该点到S集合中for(int i=1; i<=n;++i){
  dist[i]= c[v][i];
  s[i]=0;// 初始都未用过该点if(dist[i]== maxint)
   prev[i]=0;else
   prev[i]= v;}
 dist[v]=0;
 s[v]=1;
 
 // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中// 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度// 注意是从第二个节点开始,第一个为源点for(int i=2; i<=n;++i){int tmp = maxint;int u = v;// 找出当前未使用的点j的dist[j]最小值for(int j=1; j<=n;++j)if((!s[j])&& dist[j]<tmp){
    u = j;// u保存当前邻接点中距离最小的点的号码
    tmp = dist[j];}
  s[u]=1;// 表示u点已存入S集合中
 
  // 更新distfor(int j=1; j<=n;++j)if((!s[j])&& c[u][j]<maxint){int newdist = dist[u]+ c[u][j];if(newdist < dist[j]){
     dist[j]= newdist;
     prev[j]= u;}}}}
 
// 查找从源点v到终点u的路径,并输出void searchPath(int*prev,int v, int u){int que[maxnum];int tot =1;
 que[tot]= u;
 tot++;int tmp = prev[u];while(tmp != v){
  que[tot]= tmp;
  tot++;
  tmp = prev[tmp];}
 que[tot]= v;for(int i=tot; i>=1;--i)if(i !=1)cout<< que[i]<<" -> ";elsecout<< que[i]<< endl;}
 
int main(){freopen("input.txt", "r", stdin);// 各数组都从下标1开始
 
 // 输入结点数cin>> n;// 输入路径数cin>> line;int p, q, len;// 输入p, q两点及其路径长度
 
 // 初始化c[][]为maxintfor(int i=1; i<=n;++i)for(int j=1; j<=n;++j)
   c[i][j]= maxint;
 
 for(int i=1; i<=line;++i){cin>> p >> q >> len;if(len < c[p][q])// 有重边{
   c[p][q]= len;// p指向q
   c[q][p]= len;// q指向p,这样表示无向图}}
 
 for(int i=1; i<=n;++i)
  dist[i]= maxint;for(int i=1; i<=n;++i){for(int j=1; j<=n;++j)printf("%8d", c[i][j]);printf("\n");}
 
 Dijkstra(n, 1, dist, prev, c);
 
 // 最短路径长度cout<<"源点到最后一个顶点的最短路径长度: "<< dist[n]<< endl;
 
 // 路径cout<<"源点到最后一个顶点的路径为: ";
 searchPath(prev, 1, n);}

输入数据:
5
7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
输出数据:
999999 10 999999 30 100
10 999999 50 999999 999999
999999 50 999999 20 10
30 999999 20 999999 60
100 999999 10 60 999999
源点到最后一个顶点的最短路径长度: 60
源点到最后一个顶点的路径为: 1 -> 4 -> 3 -> 5

最后给出两道题目练手,都是直接套用模版就OK的:
1.HDOJ 1874 畅通工程续

2.HDOJ 2544 最短路

最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)的更多相关文章

  1. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)

    一.基于邻接表的Dijkstra算法 如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点.使用邻接表表示,可以使用 BFS ...

  2. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(一)

    一.算法介绍 迪杰斯特拉算法(英语:Dijkstra's algorithm)由荷兰计算机科学家艾兹赫尔·迪杰斯特拉在1956年提出.迪杰斯特拉算法使用了广度优先搜索解决赋权有向图的单源最短路径问题. ...

  3. c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法

    c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法 图的最短路径的概念: 一位旅客要从城市A到城市B,他希望选择一条途中中转次数最少的路线.假设途中每一站都需要换车,则这个问题反映到图上就是 ...

  4. (Dijkstra)迪杰斯特拉算法-最短路径算法

    迪杰斯特拉算法是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 算法思想:设G=(V,E)是一个带权有向图 ...

  5. 图-最短路径-Dijktra(迪杰斯特拉)算法

    1. 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉算法于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始 ...

  6. Dijkstra(迪杰斯特拉)源最短路径 小白说明

    源最短路径 小白说明 Dijkstra算法,书上其实说的很简洁,仔细看,仔细思考是会理解的.但要先理解几条引论和推理. 而自己思考的思路在不需要任何推理只从贪心思路出发,和Dijkstra有所不同,但 ...

  7. dijkstra算法(迪杰斯特拉算法)

    dijkstra算法(迪杰斯特拉算法) 用途:有向图最短路径问题 定义:迪杰斯特拉算法是典型的算法,一般的表述通常有两种方式,这里均采用永久和临时标号的方式,该算法要求图中不存在负权边 用永久和临时标 ...

  8. 图解Dijkstra(迪杰斯特拉)算法+代码实现

    简介 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的 ...

  9. 最短路之Dijkstra(迪杰斯特拉)

    一般用法: Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代 ...

随机推荐

  1. VS2010/MFC对话框:消息对话框

    消息对话框 我们在使用Windows系统的过程中经常会见到消息对话框,提示我们有异常发生或提出询问等.因为在软件开发中经常用到消息对话框,所以MFC提供了两个函数可以直接生成指定风格的消息对话框,而不 ...

  2. highlight a DOM element on mouse over, like inspect does

    highlight a DOM element on mouse over, like inspect does highlight a DOM element on mouse over, like ...

  3. MongoDB(三)mongoDB下载和安装

    软件下载 下载mongodb最新的包:http://www.mongodb.org/downloads 下载mongodb可视化界面,mongoVUE:http://download.csdn.net ...

  4. Amazon S3 API

    一.概述 Amazon s3,全称为Amazon Simple Storage  Service.EC2和S3是Amazon最早推出的两项云服务. REST,这也是比较火的一种Web服务架构.简单来说 ...

  5. MSSQL数据库统计所有表的记录数

    今天需要筛选出来库中行数不为零的表,于是动手写下了如下存储过程. CREATE PROCEDURE TableCount AS BEGIN SET NOCOUNT ON ),RowsCount INT ...

  6. eclipse修改编译路径

    右击项目--properties--java build path--点击source,修改最下方的路径即可

  7. Unable to locate appropriate constructor on class异常

    一般出现Unable to locate appropriate constructor on class这个异常,都是实体类的带参数的构造方法和使用查询语句出现偏差,两个地方的代码如下: 一般都是第 ...

  8. 建造者模式->代码示例

    <?php interface Builder{ public function head(); public function body(); public function foot(); ...

  9. ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema'

    在我想把备份的数据库导入到本地数据的时候,发生这个错误,我使用的工具是dbForge Studio for MySQL ERROR 1044 (42000): Access denied for us ...

  10. Java format 简单应用

    一.前言 String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.format("Hello %s", " ...