迪杰斯特拉(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. 用Session实现验证码

    新建一个 ashx 一般处理程序 如: YZM.ashx继承接口 IRequiresSessionState //在一般处理程序里面继承 HttpContext context 为请求上下文,包含此次 ...

  2. leetcode problem 32 -- Longest Valid Parentheses

    Longest Valid Parentheses Given a string containing just the characters '(' and ')', find the length ...

  3. Dataset

    1,if(ds == null) 这是判断内存中的数据集是否为空,说明DATASET为空,行和列都不存在!! 2,if(ds.Tables[0].Count == 0) 这应该是在内存中存在一个DAT ...

  4. jquery右下角返回顶部

    实现的效果也就是,当有滚动条是,滚动条未动或与顶部距离小于多少像素是,返回顶部按钮处于隐身状态,当滚动条与顶部距离大于一定像素时,返回顶部按钮出现,实现点击‘返回按钮’后,从当前位置回到等不位置.要先 ...

  5. odoo 清除所有运行数据

    测试odoo,如果需要一个干净的db.经常需要清除掉所有业务数据.做如下操作,较为方便 1:建立一个服务器动作,动作的python代码入下. 然后新建一个菜单,菜单动作关联到 这个动作.需要清空db, ...

  6. xcopy总是询问是文件名还是目录名

    我需要运行类似xcopy /y a.xml .\pics\b.xml很多次,但xcopy总是问我“文件名还是目录名” 可以这样通过管道来做echo f | xcopy /y a.xml .\pics\ ...

  7. xe6+firedac连接sybase

    一.Win7 X64系统安装sybase odbc: 1.  下载对应包至c:\system_odbc(文件夹名自己取,在后面注册表内容需要用到): 2.  将值信息写入到注册表内: Windows ...

  8. 一周一话题之一(EF-CodeFirst、MEF、T4框架搭建学习)

    本话题是根据郭明峰博客<MVC实用架构系列>的搭建学习总结. -->目录导航 一.数据仓储访问的构建     1.UnitOfWork的构建     2.Repository的构建 ...

  9. MySQL 对于大表(千万级),要怎么优化呢?

    http://www.zhihu.com/question/19719997 提问:如何设计或优化千万级别的大表?此外无其他信息,个人觉得这个话题有点范,就只好简单说下该如何做,对于一个存储设计,必须 ...

  10. CISCO2691的OSPF点对点密文测评测试

    都差不多,粘一个文件就能说明问题了. Router#show run Building configuration... Current configuration : bytes ! version ...