迪杰斯特拉(Dijkstra)算法
是求从某个源点到其余各顶点的最短路径,即对已知图 G=(V,E),给定源顶点 s∈V,找出 s 到图中其它各顶点的最短路径。
我总结下核心算法,伪代码如下:
Dijkstra()
{
初始化Dist、Path、final // 每次求得v0到某顶点v的最短路径
while (图的顶点数-)
{
. 找到非最短路径顶点集中距V0最近的顶点v 得到其顶点下标和距离
将v加入到最短距离顶点集合中
打印相关内容 . 依次修改其它未得到最短路径顶点的Dist[k]值
假设求得最短路径的顶点为u,
则 Dist[k] =min( Dist[k], Dist[u] + G.arcs[u][k] )
同时修改Path[k]:Path[k] = Path[u] +G.vex[k]
}
}

实例:

源代码:

 #include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std; #define MAX_VERTEX_NUM 100
#define MAX_EDGE_NUM 200
#define MAX_VERTEX_NAMELEN 100
#define INF 65535 typedef struct{
char name[MAX_VERTEX_NAMELEN];
}VerType; // 图的邻接矩阵存储结构
typedef struct{
int VertexNum,EdgeNum; // 顶点数,边数
VerType Vertex[MAX_VERTEX_NUM]; // 顶点集
int Edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 边集
}MGragh; // 邻接矩阵建图
void CreateMGragh(MGragh *Gra)
{
int i,j,k,w;
char v1[MAX_VERTEX_NAMELEN],v2[MAX_VERTEX_NAMELEN]; printf("请输入顶点数及边数(顶点数 边数)\n");
scanf("%d %d%*c",&(Gra->VertexNum),&(Gra->EdgeNum)); printf("请输入顶点信息\n");
for (i=; i<Gra->VertexNum; i++){
printf("%d.",i+);
gets(Gra->Vertex[i].name);
} // 初始化邻接矩阵
for (i=; i<Gra->VertexNum; i++){
for (j=; j<Gra->VertexNum; j++){
if (i==j){
Gra->Edge[i][j] = ; // 各点到自己的距离为0
}
else{
Gra->Edge[i][j] = INF; // 各点到不相邻的点距离为无穷
}
}
} printf("请输入边信息(顶点,顶点,权值)\n");
for (i=; i<Gra->EdgeNum; i++){
printf("%d.",i+);
scanf("%[^,]%*c%[^,]%*c%d%*c",v1,v2,&w); for (j=; j<Gra->VertexNum; j++){
for (k=; k<Gra->VertexNum; k++){
if (strcmp(Gra->Vertex[j].name,v1) == && strcmp(Gra->Vertex[k].name,v2) == ){
Gra->Edge[j][k] = w;
}
}
}
}
} int Dist[MAX_VERTEX_NUM]; // 存储VO到各点的最短路径的权值和
string ShortPath[MAX_VERTEX_NUM]; // 存储V0到各点的最短路径 void ShortPathByDijkstra(MGragh *Gra,int vo)
{
printf("\n最短路径为:\n");
int v,w,k,min;
int final[MAX_VERTEX_NUM]; // final[w]=1 表示已经求得顶点V0到Vw的最短路径 // 初始化数据
for (v=; v<Gra->VertexNum; v++){
final[v] = ; // 全部顶点初始化为未找到最短路径
Dist[v] = Gra->Edge[vo][v]; // 将与vo点有连线的顶点加上权值
if (Dist[v] != INF && Dist[v] != ){
ShortPath[v] += Gra->Vertex[vo].name;
ShortPath[v] += Gra->Vertex[v].name;
}
else{
ShortPath[v] = "";
} // 记录由V0连出去的边的路径 如AB、AC
}
Dist[vo] = ; // v0到自己的路径为0
final[vo] = ; // 标记已经找到v0到自己的最短路径 // 每次求得vo到某顶点V的最短路径
for (v=; v<Gra->VertexNum; v++){
min = INF; // 将某点加入最短路径顶点集
for (w=; w<Gra->VertexNum; w++){
if (final[w] == && Dist[w]<min){
k = w;
min = Dist[w];
}
} // 找到非最短路径顶点集中距V0最近的顶点 得到其顶点下标和距离
final[k] = ; // 将目前找到最近的顶点置1 即将该点加入最短路径顶点集
printf("%d\t",Dist[k]);
cout << ShortPath[k] << endl; // 修正当前最短路径及距离
for (w=; w<Gra->VertexNum; w++){
// 如果经过v顶点的路径比现在这条路径的长度短的话就更新
if (final[w] == && (min+Gra->Edge[k][w]) < Dist[w]){
Dist[w] = min + Gra->Edge[k][w];
ShortPath[w] = ShortPath[k];
ShortPath[w] += Gra->Vertex[w].name;
}
}
}
} int main()
{
MGragh g;
CreateMGragh(&g);
ShortPathByDijkstra(&g,);
return ;
}

测试用例及结果:

Dijkstra算法构造单源点最短路径的更多相关文章

  1. Bellman-Ford & SPFA 算法——求解单源点最短路径问题

    Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好 ...

  2. Til the Cows Come Home(poj 2387 Dijkstra算法(单源最短路径))

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 32824   Accepted: 11098 Description Bes ...

  3. Dijkstra算法解决单源最短路径

    单源最短路径问题:给定一个带权有向图 G = (V, E), 其中每条边的权是一个实数.另外,还给定 V 中的一个顶点,称为源.现在要计算从源到其他所有各顶点的最短路径长度.这里的长度是指路上各边权之 ...

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

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

  5. 【转】Dijkstra算法(单源最短路径)

    原文:http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html 单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路 ...

  6. Dijkstra算法详细(单源最短路径算法)

    介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...

  7. Dijkstra算法求单源最短路径

    Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店 ...

  8. SPFA算法与dijkstra算法求单源最短路径的比较

    SPFA是运用队列,把所有的点遍历到没有能更新的,点可以重复入队 如题http://www.cnblogs.com/Annetree/p/5682306.html dijkstra是每次找出离源点最近 ...

  9. Dijkstra单源点最短路径算法

    学习参考: Dijkstra算法(单源最短路径) 最短路径—Dijkstra算法和Floyd算法 使用的图结构: 邻接矩阵: -1 20 -1 25 80-1 -1 40 -1 -1-1 -1 -1 ...

随机推荐

  1. apache的MPM机制-prefork

    apache是基于模块化设计的. 关于基础的服务,也采用了模块化的设计,但是这个模块是具有排他性的,同一时间只能有一个得到调用. MPM模块(multi processing module) 多处理模 ...

  2. varchar(n),nvarchar(n) 长度、性能、及所占空间分析 nvarchar(64) nvarchar(128) nvarchar(256)(转)

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  3. HTML新元素

    <canvas> 标签定义图形,比如图表和其他图像.该标签基于 JavaScript 的绘图 API <audio> 定义音频内容 <video> 定义视频(vid ...

  4. C语言中字符型和字符串型的区别?

    C语言中只有字符型类型,没有字符串型类型.字符类型用一个带符号的8位二进制编码表示,其性质与int相同,只是只有一个字节.表示字符的ASCII编码使用其中的0~127,所以要明白字符类型(char)其 ...

  5. “T”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法

    最近在项目中,使用EF编程时,在使用泛型类型的过程中,写了一上午,结果生成时,编译不通过,报出如下错误: “T”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法.如图: 找了好久,终 ...

  6. POJ 2635 The Embarrassed Cryptographer 大数模

    题目: http://poj.org/problem?id=2635 利用同余模定理大数拆分取模,但是耗时,需要转化为高进制,这样位数少,循环少,这里转化为1000进制的,如果转化为10000进制,需 ...

  7. VCC,VDD,VEE,VSS,VPP 表示的意义

    转自VCC,VDD,VEE,VSS,VPP 表示的意义 VCC,VDD,VEE,VSS,VPP 表示的意义 版本一: 简单说来,可以这样理解: 一.解释 VCC:C=circuit 表示电路的意思, ...

  8. ECMall系统请求跳转分析

    ecmall是一个基于mvc模式框架系统,跟thinkphp有点像.先从ecmall的入口开始,ecmall入口文件upload/index.php.admin.php: index.php启动ecm ...

  9. 【GDOI 2011 DAY2 T3】零什么的最讨厌了 (快速求阶乘、中国剩余定理)

    问题描述: 林记在做数学习题的时候,经常遇到这种情况:苦思冥想了很久终于把问题解出来,结果发现答案是0,久而久之林记在得到习题答案是0的时候就没有了做出一道难题的成就感.于是林记决定:以后出题,答案一 ...

  10. POJ - 3264 Balanced Lineup 线段树解RMQ

    这个题目是一个典型的RMQ问题,给定一个整数序列,1~N,然后进行Q次询问,每次给定两个整数A,B,(1<=A<=B<=N),求给定的范围内,最大和最小值之差. 解法一:这个是最初的 ...