声明:图片及内容基于:https://www.bilibili.com/video/BV16C4y1H7Zc?from=articleDetail

最短路径

Dijkstra算法

原理

数据结构

核心代码

findMinDist()

int MGraph::findMinDist(){
int length=INFINIT;
for(int i=0;i<vertexNum;i++){
if(s[i]==0){
if(length>dist[i]&&dist[i]!=0&&dist[i]!=INFINIT){
length=i; //注意记录的是下标,我原来写成length=dist[i]了,太惨了
}
}
}
return length;
}

displayPath()

void MGraph::displayPath(){            //打印最短路径
for(int i=0;i<vertexNum;i++){
if(i==startV) cout<<i<<endl; //起点直接打印
if(i!=startV){ //其他结点
int tmp=i;
stack<int> s; //逆序输出使用栈
while(tmp!=startV){
s.push(path[tmp]);
tmp=path[tmp];
}
while(!s.empty()){
cout<<s.top()<<"->";
s.pop();
}
cout<<i;
cout<<endl;
}
}
}

Dijkstra(int startV)

void MGraph::Dijkstra(int startV){
this->startV=startV; //别忘了,startV也是MGraph的数据成员
for(int i=0;i<vertexNum;i++){
dist[i]=arc[startV][i]; //dist数组初始化 if(dist[i]!=INFINIT) //path数组初始化
path[i]=startV;
else
path[i]=-1;
}
for(int i=0;i<vertexNum;i++) //s数组初始化
s[i]=0; s[startV]=1; //startV放入集合
int num=1; //集合数据个数1
while(num<vertexNum){
int min=findMinDist(); //min是当前dist数组中最短路径的下标,前提是s[i]=0,即查找的
//是集合的补集元素
s[min]=1; //min放入集合
for(int i=0;i<vertexNum;i++){ //更新dist和path数组
if(s[i]==0&&(dist[i]>dist[min]+arc[min][i])){
dist[i]=dist[min]+arc[min][i];
path[i]=min;
}
}
num++;
}
displayPath(); //显示全部最短路径
}

完整代码

#include<iostream>
#define MAX 50
#define INFINIT 65535
#include <stack>
using namespace std;
class MGraph{
private:
int vertexNum,arcNum; //顶点数,边数
int arc[MAX][MAX]; //邻接矩阵
int vertex[MAX]; //顶点信息
int dist[MAX]; //记录单源到每个点的最短路径的长度
int path[MAX]; //记录当前从某点到某点的最短路径,存放的是某点起点的顶点信息
int s[MAX]; //记录已经确定的最短路径的结点集合
int startV;
public:
MGraph(int v[],int n,int e);
void display();
void Dijkstra(int startV);
int findMinDist();
void displayPath();
void displayDistPathS();
};
void MGraph::displayDistPathS(){
cout<<"dist:"<<endl;
for(int i=0;i<vertexNum;i++){
cout<<dist[i]<<" ";
}
cout<<endl;
cout<<"path:"<<endl;
for(int i=0;i<vertexNum;i++){
cout<<path[i]<<" ";
}
cout<<endl;
cout<<"S:"<<endl;
for(int i=0;i<vertexNum;i++){
cout<<s[i]<<" ";
}
cout<<endl;
}
MGraph::MGraph(int v[],int n,int e){ //n是顶点数,e是边数
vertexNum=n;
arcNum=e;
for(int i=0;i<vertexNum;i++){
vertex[i]=v[i];
}
for(int i=0;i<arcNum;i++){ //初始化邻接矩阵
for(int j=0;j<arcNum;j++){
if(i==j) arc[i][j]=0;
else arc[i][j]=INFINIT;
}
}
int vi,vj,w;
for(int i=0;i<arcNum;i++){
cout<<"请输入有向边的两个顶点和这条边的权值"<<endl;
cin>>vi>>vj>>w; //输入边依附的两个顶点的编号 和权值
arc[vi][vj]=w; //有边标志
}
}
void MGraph::display(){
cout<<"邻接矩阵:"<<endl;
for(int i=0;i<vertexNum;i++){
for(int j=0;j<vertexNum;j++){
if(arc[i][j]==INFINIT)
cout<<"∞"<<"\t";
else cout<<arc[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl;
cout<<"结点信息:"<<endl;
for(int i=0;i<vertexNum;i++){
cout<<vertex[i]<<" ";
}
cout<<endl;
}
int MGraph::findMinDist(){
int length=INFINIT;
for(int i=0;i<vertexNum;i++){
if(s[i]==0){
if(length>dist[i]&&dist[i]!=0&&dist[i]!=INFINIT){
length=i; //注意记录的是下标,我原来写成length=dist[i]了,太惨了
}
}
}
return length;
}
void MGraph::displayPath(){ //打印最短路径
for(int i=0;i<vertexNum;i++){
if(i==startV) cout<<i<<endl; //起点直接打印
if(i!=startV){ //其他结点
int tmp=i;
stack<int> s; //逆序输出使用栈
while(tmp!=startV){
s.push(path[tmp]);
tmp=path[tmp];
}
while(!s.empty()){
cout<<s.top()<<"->";
s.pop();
}
cout<<i;
cout<<endl;
}
}
}
void MGraph::Dijkstra(int startV){
this->startV=startV; //别忘了,startV也是MGraph的数据成员
for(int i=0;i<vertexNum;i++){
dist[i]=arc[startV][i]; //dist数组初始化 if(dist[i]!=INFINIT) //path数组初始化
path[i]=startV;
else
path[i]=-1;
}
for(int i=0;i<vertexNum;i++) //s数组初始化
s[i]=0; s[startV]=1; //startV放入集合
int num=1; //集合数据个数1
while(num<vertexNum){
int min=findMinDist(); //min是当前dist数组中最短路径的下标,前提是s[i]=0,即查找的
//是集合的补集元素
s[min]=1; //min放入集合
for(int i=0;i<vertexNum;i++){ //更新dist和path数组
if(s[i]==0&&(dist[i]>dist[min]+arc[min][i])){
dist[i]=dist[min]+arc[min][i];
path[i]=min;
}
}
num++;
}
displayPath(); //显示全部最短路径
} int main(){
int n,e;
int v[MAX];
cout<<"请输入顶点数和边数"<<endl;
cin>>n>>e;
cout<<"请输入顶点信息"<<endl;
for(int i=0;i<n;i++){
cin>>v[i];
}
cout<<"请输入起点:"<<endl;
int t;
cin>>t;
MGraph mgraph(v,n,e);
mgraph.display();
mgraph.Dijkstra(t);
mgraph.displayDistPathS();
return 0;
}

输入:

7 12
0 1 2 3 4 5 6
0
0 1 4
0 2 6
0 3 6
1 2 1
1 4 7
2 4 6
2 5 4
3 2 2
3 5 5
4 6 6
5 4 1
5 6 8

输出:

邻接矩阵:
0 4  6  6 ∞  ∞ ∞
∞ 0 1  ∞ 7  ∞ ∞
∞ ∞ 0 ∞ 6  4 ∞
∞ ∞ 2 0 ∞  5 ∞
∞ ∞ ∞ ∞ 0  ∞ 6
∞ ∞ ∞ ∞ 1  0 8
∞ ∞ ∞ ∞ ∞ ∞ 0

结点信息:
0 1 2 3 4 5 6
0
0->1
0->1->2
0->3
0->1->4
0->1->2->5
0->1->4->6
dist:
0 4 5 6 11 9 17
path:
0 0 1 0 1 2 4
S:
1 1 1 1 1 1 1

最短路径(Dijskra算法)的更多相关文章

  1. 算法对比:Prim算法与Dijskra算法

    在图论中,求MST的Prim算法和求最短路的Dijskra算法非常像.可是我一直都对这两个算法处于要懂不懂的状态,现在,就来总结一下这两个算法. 最小生成树(MST)—Prim算法: 算法步骤: •将 ...

  2. 单源最短路径——Dijkstra算法学习

    每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...

  3. 网络最短路径Dijkstra算法

    最近在学习算法,看到有人写过的这样一个算法,我决定摘抄过来作为我的学习笔记: <span style="font-size:18px;">/* * File: shor ...

  4. 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?

    简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...

  5. 单源最短路径Dijkstra算法,多源最短路径Floyd算法

    1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...

  6. 图中最短路径的算法--dijiska算法C语言实现

    #include <stdio.h> #include <stdlib.h> #define ERROR_NO_MEM -1 /*内存不足的错误码*/ #define MAX_ ...

  7. 最短路径-Dijkstra算法与Floyd算法

    一.最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1    ADE:2   ADCE:3   ABCE:3 ②在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径 ...

  8. 数据结构实验之图论七:驴友计划 ( 最短路径 Dijkstra 算法 )

    数据结构实验之图论七:驴友计划 Time Limit: 1000 ms           Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...

  9. SDUT OJ 图结构练习——最短路径 ( Floyed 算法 AND Dijkstra算法)

    图结构练习——最短路径 Time Limit: 1000 ms            Memory Limit: 65536 KiB Submit Statistic Discuss Problem ...

随机推荐

  1. Express vs Koa

    Express vs Koa https://www.esparkinfo.com/express-vs-koa.html https://www.cleveroad.com/blog/the-bes ...

  2. C++算法代码——[TYVJ]单数?双数?

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1178 题目描述 Bessie那惨无人道的二年级老师搞了一个有  N  (1  < ...

  3. 【Python】set 与 list ——如何对列表进行去重?

    在Python中,形如 {1,2,3,4,5} 这样的数据类型叫做"集合",外形酷似列表list [1,2,3,4,5] 但是集合与列表有很多区别,具体表现在以下几方面: List ...

  4. 23_MySQL单行和多行子查询语法规则(重点)

    本节涉及SQL语句: -- 如何用子查询查找FORD和MARTIN两个人的同事? 1 WHERE子查询 SELECT ename FROM t_emp WHERE deptno IN (SELECT ...

  5. 用一次就会爱上的cli工具开发

    本文转载自用一次就会爱上的cli工具开发 写在前面 最近接手任务--使用nodejs开发一个公司内部使用的cli工具,简而言之就是输入一行命令快速搭建好项目结构,也可以通过不同的命令引入不同的文件. ...

  6. 创建一个springboot项目

    进入https://start.spring.io/ 再点击GENERATE,下载解压即可 注意配置好阿里云的仓库镜像,免得依赖无法下载 不下载最新版springboot是因为我在测试中遇到了问题,貌 ...

  7. Hive-常见调优方式 && 两个面试sql

    Hive作为大数据领域常用的数据仓库组件,在设计和开发阶段需要注意效率.影响Hive效率的不仅仅是数据量过大:数据倾斜.数据冗余.job或I/O过多.MapReduce分配不合理等因素都对Hive的效 ...

  8. Vue脚手架中默认的margin怎么清除

    问题情景:开发中发现我的项目四周有白边,但是并没有设置样式 问题原因:vue脚手架中静态文件夹public中的index.html造成的 解决方案:找到vue脚手架中index.html页面,设置ma ...

  9. IO、NIO、BIO的区别

    我们首先得明白什么是同步,异步,阻塞,非阻塞,只有这几个单个概念理解清楚了,然后在组合理解起来,就相对比较容易了. IO模型主要分类: 同步(synchronous) IO和异步(asynchrono ...

  10. Python3.x 基础练习题100例(11-20)

    练习11: 题目: 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 分析: 兔子的规律为数列1,1,2, ...