Dijkstra——单源最短路径
算法思想
①从一个源点开始,找距离它最近的点顶点v
②然后以顶点v为起点,去找v能到达的顶点w,即v的邻居
比较源点直接到 v的距离和(源点到v的距离+v到w的距离)
若大于后者则更新源点的到w的开销
③然后去掉这个顶点v,去寻找下一个到距离源点最近的顶点重复②
最后更新完所有顶点
算法思路
1.用邻接表或者一个二维数组(邻接矩阵)来存储图
2.设置dist存储到源点的最短距离
known标记顶点是被处理
path记录路径(到达该顶点的上一个顶点)
3.这步的实现和算法思想中描述的一样
4.递归显示出源点到各个顶点的路径
代码实现
下面是完整的代码实现,分别用了邻接表和邻接矩阵来存图
样图如下

邻接矩阵存图
#include <iostream>
#include <cstdlib>
#define Infinity 10000
#define VERSIZE 8
#define notvertex -1
using namespace std;
typedef int Vertex;
int dist[VERSIZE];//存储各顶点到源点的最短距离
bool S[VERSIZE];//将处理过的顶点设置为true
Vertex path[VERSIZE];//存储到该顶点的上一个顶点
void ReadGraph(int Graph[VERSIZE][VERSIZE], int m)// 边m
{
;
Vertex u, v;
int weight;
; i <= m; i++)
{
cout << "请输入第" << i << "条边:";
cin >> u >> v;
cout << "请输入边(" << u << "," << v << ")的权重:";
cin >> weight;
Graph[u][v] = weight;
}
}
//在没处理过的顶点里 找出距离源点最近的顶点
Vertex FindMinIndex()
{
int min = Infinity;
Vertex min_index = ;
; i< VERSIZE; i++)
{
if (!S[i] && dist[i]<min)
{
min = dist[i];
min_index = i;
}
}
return min_index;
}
//算法关键
void Dijkstra(int Graph[VERSIZE][VERSIZE], Vertex source)
{
;
// 初始化数组 从顶点为1开始能直接到达source的 初始化dis数组 0代表不可达
; i < VERSIZE; i++)
{
dist[i] = (Graph[source][i] == ? Infinity : Graph[source][i]);
S[i] = false;
if (dist[i] != Infinity)
path[i] = source;
else
path[i] = notvertex;
}
//源点到自身
dist[source] = ;
S[source] = true;
//循环VERSIZE-1次
; count < VERSIZE; count++)
{
Vertex u = FindMinIndex();//找出距离源点最近的顶点
S[u] = true;//标记为已知
; v < VERSIZE; v++)
{
&& !S[i])//u可达v 且 v未知
{
if (dist[v] >(Graph[u][v] + dist[u]))
{
dist[v] = Graph[u][v] + dist[u];
path[v] = u;
}
}
}
}
}
void PrintDist(Vertex source)
{
;
printf("Source vertex Dist\n");
; i< VERSIZE; i++)
{
if (dist[i] != Infinity)
printf("%d -> %d\t%d\n", source, i, dist[i]);
else
printf("%d -> %d\tInfinity\n", source, i);
}
}
//输出路径
void PrintPath(int v)
{
if (path[v] != notvertex)
{
PrintPath(path[v]);
printf("--->");
}
printf("%d", v);
}
int main()
{
,j=;
};
; i < VERSIZE; i++)//初始化二维数组
{
; j < VERSIZE; j++)
Graph[i][j] = ;
}
ReadGraph(Graph, );
Dijkstra(Graph, );//源点是1
PrintDist();
printf("源点1顶点7的路径:\n");
PrintPath();//打印从源点到顶点7的路径
system("pause");
;
}
运行结果

邻接表存图
#include <iostream>
#include <cstdlib>
#define VERSIZE 8
#define NotVertex -1
#define Infinity 100000
using namespace std;
typedef int Vertex;
typedef struct vernode VerNode;//定义顶点结构
typedef struct tablelist Table;//定义邻接表
struct vernode
{
Vertex ver;
int weight;//权重
VerNode * pNext;
};
struct tablelist
{
VerNode header;
bool known;
int dist;
Vertex path;
}T[VERSIZE];
//初始化标表+读图
void InitTable(Table T[], int n, int m)//顶点数n 边数m
{
;
; i <= n; i++)//初始化表头
{
T[i].header.ver = i;
T[i].header.weight = ;//到自身的权重为0
T[i].header.pNext = NULL;
T[i].dist = Infinity;
T[i].known = false;
T[i].path = NotVertex;
}
Vertex u, v;//边(u,v)
;
VerNode * ptemp;
; i <= m; i++)
{
cout << "请输入第" << i << "条边:";
cin >> u >> v;
cout << "请输入边(" << u <<","<< v << ")的权重:";
cin >> wei;
ptemp = (VerNode*)malloc(sizeof(VerNode));
ptemp->ver = v;
ptemp->weight = wei;
ptemp->pNext = T[u].header.pNext;
T[u].header.pNext = ptemp;
}
}
//找出到源点距离最小的顶点
Vertex FindMinIndex(Table T[], int n)
{
;
int min = Infinity;
Vertex min_index = NotVertex;
; i <= n; i++)
{
if (!T[i].known && T[i].dist < min)
{
min = T[i].dist;
min_index = i;
}
}
return min_index;
}
//下面是算法关键步骤啦 dijkstra算法
void Dijkstra(Table T[], int n, Vertex source)//source源点 顶点数n
{
;
T[source].dist = ;//源点到源点的距离为0
T[source].known = true;//源点已知
//在做循环处理前 还要赋值给能直接到达源点的顶点的dist数据
VerNode * ptemp;//能直接到达源点的顶点
ptemp = T[source].header.pNext;
Vertex w;
while (ptemp)
{
w = ptemp->ver;
T[w].dist = ptemp->weight;
T[w].path = source;
ptemp = ptemp->pNext;
}
Vertex v;
//处理n-1个顶点
; i <= n-;i++)
{
//找出到源点距离最小的顶点
v = FindMinIndex(T, n);
if (v == NotVertex)
break;
T[v].known = true;
ptemp = T[v].header.pNext;//找出顶点V所能到的顶点看是否能跟新他们的dist
while (ptemp)
{
w = ptemp->ver;
if (!T[w].known && T[w].dist > ptemp->weight + T[v].dist)//进行跟新操作
{
T[w].dist = ptemp->weight + T[v].dist;
T[w].path = v;
}
ptemp = ptemp->pNext;
}
}
}
//下面输出我们的最短路径吧
void PrintPath(Table T[],Vertex v)
{
if (T[v].path != NotVertex)
{
PrintPath(T, T[v].path);
cout << " ---> ";
}
cout << v;
}
int main()
{
Vertex v;
InitTable(T, , );
Dijkstra(T, , );
cout << "源点1到各个顶点的最短路径如下:" << endl;
; v <= ; v++)
{
PrintPath(T, v);
cout << endl;
}
system("pause");
;
}
运行结果

需要其他的信息可以根据需要输出
修改补充后的:SakuraOne Dijkstra单源最短路径算法
THOUGHTS
算法思想好理解 实现的话也挺好理解 但是关键就是理解的程度
学习嘛 就是不断重复的过程 对想想就对了还有多动手画画
Dijkstra——单源最短路径的更多相关文章
- Dijkstra 单源最短路径算法
Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...
- Dijkstra单源最短路径,POJ(2387)
题目链接:http://poj.org/problem?id=2387 Dijkstra算法: //求某一点(源点)到另一点的最短路,算法其实也和源点到所有点的时间复杂度一样,O(n^2); 图G(V ...
- 【模板 && 拓扑】 Dijkstra 单源最短路径算法
话不多说上代码 链式前向星233 #include<bits/stdc++.h> using namespace std; ,_max=0x3fffffff; //链式前向星 struct ...
- Bellman-Ford 单源最短路径算法
Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...
- 单源最短路径算法---Dijkstra
Dijkstra算法树解决有向图G=(V,E)上带权的单源最短路径问题,但是要求所有边的权值非负. 解题思路: V表示有向图的所有顶点集合,S表示那么一些顶点结合,从源点s到该集合中的顶点的最终最短路 ...
- Til the Cows Come Home(poj 2387 Dijkstra算法(单源最短路径))
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 32824 Accepted: 11098 Description Bes ...
- 单源最短路径——dijkstra算法
dijkstra算法与prim算法的区别 1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...
- 【转】Dijkstra算法(单源最短路径)
原文:http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html 单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路 ...
- 图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法
Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径 ...
随机推荐
- apache学习笔记
httpd -k restart -n apache24 [注意在wamp下名字叫wampapache] http://blog.sina.com.cn/s/blog_692a024c0102vuq ...
- oracle odbc mysql 字段不全
主要是字段集不对,mysql的字符集默认设置为utf8,odbc才是unicode编码连接,无法转发.选择ansi连接方式即可.
- java开发师笔试面试每日12题(3)
1.JDK和JRE的区别是什么? Java运行时环境(JRE)是将要执行Java程序的Java虚拟机.它同时也包含了执行applet需要的浏览器插件.Java开发工具包(JDK)是完整的Java软件开 ...
- python猜数字GUI版本V0.2
使用类方式编写猜数字游戏GUI版本. 思路:初始化数字以及初始化wegdits,编写button click event判断代码的函数,每猜一次点击button调用一次该函数,并计算猜的次数.如果猜对 ...
- Stacking Plates(存档待续.....(没有写思路和程序))
问题描述 盘子装运公司是一家网络零售商,顾名思义,是一家只销售盘子的公司.该公司销售的盘子由不计其数的生产厂商提供,品种是全宇宙最多的,为此公司的员工倍感自豪. 在最近的一次成本分析中,公司员工发现, ...
- 【HDU1000】A+B Problem
题目来源:www.acm.hdu.edu.cn 题目编号:1000 A+B Problem /*----------------------------------------原题目-------- ...
- 《HTTP权威指南》5-Web服务器
各种形状,风格,尺寸的Web服务器 Web服务器会对HTTP请求进行处理并提供响应.Web服务器有着不同的风格,形状和尺寸但是不管功能,外貌,风格有何差异,所有的Web服务器都能够接收请求资源的HTT ...
- [转] Vmware vs Virtualbox vs KVM vs XEN: virtual machines performance comparison
http://www.ilsistemista.net/index.php/virtualization/1-virtual-machines-performance-comparison.html? ...
- 前端“黑话”polyfill
前言 在Web前端开发这个日新月异的时代,总是需要阅读一些最新的英文技术博客来跟上技术的发展的潮流.而有时候会遇到一些比较高频的“黑话”,在社区里面可能已经是人人皆知的“共同语言”,而你接触的少就偏偏 ...
- UnicodeDecodeError:utf-8codeccantdecodebyte0xb9inposition0:invalidstartbyte
相信这个问题大家都会以为是编码的问题,当然原本我也以为是编码问题! 然后试了各种方案!都是以失败告终! 哈哈哈,后来解决了,原来真是闹了个大笑话............ 这是因 ...