最近在准备ccf,各种补算法,图的算法基本差不多看了一遍。今天看的是Dijkstra算法,这个算法有点难理解,如果不深入想的话想要搞明白还是不容易的。弄了一个晚自习,先看书大致明白了原理,就根据书上的代码敲,边敲边深入思考,第一遍敲完运行失败,然后回过头在分析代码,改进还是失败。经过三次修改总算勉强跑起来了,但是结果还是不对,找了半天也找不出来。感觉整个人都不好了,弄了快三个小时结果还是有问题。时间差不多就回宿舍,在路上边走边想终于找到自己代码的问题了,回到宿舍代码修改后终于完美运行。经过一晚上的不断思考深入,反复推敲,得到了完美结果,付出和回报是成正比的。

  好了!大致讲一下自己对这个算法的理解吧!首先要想弄明白这个算法还是得了解一下广度优先搜索的原理,这个算法就是基于广搜的原理得出来的一个算法。算法的核心又有点贪心算法的味道,所以说这个算法相当经典。Dijkstra算法是求单个节点到图中其他所有节点的最短距离,为了解决这个问题,首先要引入三个数组D[i](记录起始点到其他各点的最短距离),mark[i](表示每个节点的是否已经访问过),p[i](记录每个节点的前驱结点,便于观察最后到各个顶点的路径)。

  Dijkstra算法的执行步骤:1.先初始化D[i]=v与i之间的距离(若两点不相连则为INIFY),mark[i]=0,p[i]=0,并将起始节点v的mark[v]=0;

              2.遍历剩余的节点,找出剩余节点与v之间的距离(初始状态下除去相连的节点间有距离外其余所有节点间距离为INIFY),不相连的节点依然设为INIFY不变。找出其中与v距离最小的那个点k,mark[k]=1;

               3.遍历所有节点,对其中mark[i]==0的点与k点的距离+2中的那个最小距离与D[i]比较,若小于D[i]则更新D[i],并将p[i]标记为k(k为该节点的前驱)。

             4.遍历完后得到的D[i]就是v到各个节点的最短距离.

#include<iostream>

using namespace std;
#define INFTY 10000 class Graph
{
public:
Graph(int n); //构造函数初始化
~Graph(); //析构函数销毁
void SetEdge(int v1,int v2,int weight); //设置图中的相连边及其权值
void Dijkstra(int v0); //迪杰斯特拉算法
void Print();
private:
int numVex; //顶点数
int numEdge; //边数
int **matrix; //图
int *mark; //顶点标记
int *p; //表示PathMatrix最短路径的前驱结点
int *D; //表示ShortPathTa即两点间的带权长度
}; Graph::Graph(int n)
{
numVex=n;
numEdge=;
mark=new int[numVex];
p=new int[numVex];
D=new int[numVex];
matrix=new int*[numVex];
for(int i=;i<numVex;i++)
{
matrix[i]=new int[numVex];
}
for(int i=;i<numVex;i++)
{
mark[i]=;
p[i]=;
D[i]=;
}
for(int i=;i<numVex;i++)
{
for(int j=;j<numVex;j++)
{
matrix[i][j]=matrix[j][i]=INFTY;
}
}
} Graph::~Graph()
{
delete []p;
delete []D;
delete []mark;
for(int i=;i<numVex;i++)
{
delete []matrix[i];
}
delete []matrix;
} void Graph::SetEdge(int v1,int v2,int weight)
{
matrix[v1][v2]=matrix[v2][v1]=weight;
} void Graph::Dijkstra(int v0)
{
int k,min;
for(int i=;i<numVex;i++)
{
D[i]=matrix[v0][i];
}
D[v0]=;
mark[v0]=; //表示已经求得v0点的最短路径
for(int i=;i<numVex;i++)
{
min=INFTY;
for(int j=;j<numVex;j++)
{
if(!mark[j] && D[j]<min)
{
k=j;
min=D[j];
}
}
mark[k]=; //表示从v0到k已经找到最短路径 //修正目前的最短路径
for(int j=;j<numVex;j++)
{
if(!mark[j] && (min+matrix[k][j]<D[j]))
{
D[j]=min+matrix[k][j]; //修改当前路径的长度
p[j]=k; //存放当前节点的前驱
}
}
}
} void Graph::Print()
{
cout<<"v0到各顶点的最短距离:"<<endl;
for(int i=;i<numVex;i++)
{
cout<<D[i]<<" ";
}
cout<<endl;
cout<<"各顶点的前驱顶点:"<<endl;
for(int i=;i<numVex;i++)
{
cout<<p[i]<<" ";
}
} int main()
{
int n,m,t;
cout<<"请输入顶点数n和边数m"<<endl;
cin>>n>>m;
Graph G(n);
int v1,v2,weight;
cout<<"请输入顶点v1,v2及两顶点间边的权值"<<endl;
for(int i=;i<m;i++)
{
cin>>v1>>v2>>weight;
G.SetEdge(v1,v2,weight);
}
cout<<"请输入迪杰斯特拉算法的起始顶点"<<endl;
cin>>t;
G.Dijkstra(t);
G.Print(); return ;
}

  代码自己写的,可以完美运行!希望对大家有帮助。

关于dijkstra算法的一点理解的更多相关文章

  1. 迪杰斯特拉(Dijkstra)算法描述及理解

    Dijkstra算法是一种计算单源最短无负边路径问题的常用算法之一,时间复杂度为O(n2) 算法描述如下:dis[v]表示s到v的距离,pre[v]为v的前驱结点,用以输出路径,vis[v]表示该点最 ...

  2. 对dijkstra算法的自我理解,c#例子

    dijkstra该算法主要应用在求解最短路径,从最近点开始,广度搜索. 假设有向图中有10个顶点,求其中某个顶点a到其它顶点的最短路径..满足贪心算法的2个标准.时间复杂度为O(N2) 此问题可以进行 ...

  3. dijkstra算法:寻找到全图各点的最短路径

    dijkstra算法介绍:即迪杰斯特拉算法,是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止,是一种广度优先 ...

  4. paxos算法之粗浅理解

    paxos出身 paxos出身名门,它爹是没多久前获得图灵奖的在分布式领域大名鼎鼎的LeslieLamport. paxos为何而生 那么Lamport他老人家为什么要搞这个东东呢,不是吃饱了撑的,而 ...

  5. 一步一步深入理解Dijkstra算法

    先简单介绍一下最短路径: 最短路径是啥?就是一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两顶点之间经过的边上权值之和最小的路径. 并且我们称路径上的第 ...

  6. 理解最短路径-Dijkstra算法

    最短路径—Dijkstra算法和Floyd算法 透彻理解迪杰斯特拉算法 Dijkstra算法的使用条件:图中不存在负权边. ---------------------------有待验证------- ...

  7. 通俗易懂理解——dijkstra算法求最短路径

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径.它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止 ###基本思想 通过Dij ...

  8. Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解

    /* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...

  9. 最短路:我的理解--Dijkstra算法

    最短路径:Dijkstra算法 用来计算从一个点到其他所有点的最短路径的算法,是一种单源最短路径算法.也就是说,只能计算起点只有一个的情况. Dijkstra的时间复杂度是O (N2),它不能处理存在 ...

随机推荐

  1. 报文解析及CRC类

    /// <summary> /// 报文解析转换类 /// </summary> public class DatagramConvert { public static En ...

  2. C++ 控制台代码输出控制

    在C++控制台应用程序中可以控制控制台输出的字体颜色和 接受任意按键退出 #ifndef CONSOLE_UTILS_H #define CONSOLE_UTILS_H #include <wi ...

  3. HTML以及CSS的作用和理念

    首先,在学习之前,这些是必要知道的东西.什么是HTML,什么是CSS 它们有什么用?又能做什么? 了解HTML和CSS的用途,能更有利我们快速,高效的学习它们. 那么,关于这两者,我就用我通俗的语言像 ...

  4. java多态性,父类引用指向子类对象

    父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog.其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类. Animal animal = new C ...

  5. java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**

    在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...

  6. delegate、notification、KVO场景差别

    delegate: 编译器会给出没有实现代理方法的警告 一对一 使用weak而不是assign,或者vc消失时置为nil 可以传递参数,还可以接收返回值 notification: 编译期无法排错 一 ...

  7. 朴素贝叶斯(NB)复习总结

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 贝叶斯分类算法是统计学的一种分类方法,其分类原理就是利用贝叶斯公式根据某 ...

  8. 应用Web.Config配置网站

    1.配置数据库连接 在ASP.NET中配置数据库连接的两种方式: appSettings和connectionStrings 命名空间: using System.Configuration; 1)a ...

  9. 服务器.htaccess 详解以及 .htaccess 参数说明(转载)

    htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作为用户,所能使用的命令受到限 ...

  10. ajax局部刷新后,如何让局部中的百度分享重新加载

    我这个人不怎么喜欢说太多话,看几个图你们就懂了 Ajax前 Ajax之后 原因分析 解决方法 收工 百度分享是集成了众多主流第三方网站分享和收藏按钮的工具. 通过百度分享轻松将主流第三方网站的分享按钮 ...