贪心算法(Dijkstra)解决单源最短路径问题(C++)
Posted 合肥编程思维
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心算法(Dijkstra)解决单源最短路径问题(C++)相关的知识,希望对你有一定的参考价值。
问题描述
给定一个带权有向图G=(V,E),其中每条边的权是非负实数。另外,给定V中的一个顶点,称为源。现在要计算从源到所有其他各顶点的最短路径长度。这里的路长度是指路上各边权之和。这个问题通常称为单源最短路径问题。
算法基本思想
Dijkstra算法是解决单源最短路径问题的一个贪心算法,其基本思想是,设置顶点集合S,并不断地做贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。初始时,S中仅含有源。
设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。
Dijkstra算法每次从V-S中取出具有最短路径长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中的顶点,dist就记录了从源到所有其他顶点之间的最短路径。(注意dist表示的都是源到顶点的最短距离)
代码
template<class Type>
void Dijkstra(int n,int v,Type dist[],int prev[],Type **c){
//n:图中顶点个数,v:源结点,dist:从源结点出发到各个顶点的距离,prev:通过最短路径到当前结点的上一结点
//c:一个二维数组,用来存储各个边之间的权重
bool s[maxint];//用来标识某一结点是否已经进入了我们的集合S(存在于最短路径中的点都存在于S中)
for(int i = 1;i <= n;i++)
{
dist[i] = c[v][i];//初始化源到各点距离,如果不直通就设为maxint
s[i] = false;
if(dist[i] == maxint)
prev[i] = 0;//不连通时前序结点设为0
else
prev[i] = v;
}
dist[v] = 0;
s[v] = true;
for(int i = 1;i < n;i++)
{
int temp = maxint;
int u = v;
for(int j = 1;j <= n;j++)
{
//通过最外层循环,我不断找到当前未加入S中的结点距源节点距离最小的点,将其连入路径中
if((!s[j]) && (dist[j]) < temp)
{
u = j;
temp = dist[j];
}
}
s[u] = true;//u结点也被纳入S集合,接下来的点可以计算和u的距离,从而计算到v的距离
for(int j = 1;j <= n;j++)
{
if((!s[j]) && c[u][j] < maxint)
{
Type newdist = dist[u] + c[u][j];
if(newdist < dist[j])
{
dist[j] = newdist;
prev[j] = u;
}
}
}
}
}
迭代的过程:
如果我们想要知道具体路径就可以利用我们的prev数组,prev[i]存放的就是最短路径中i前面的一个结点。初始化时,对于所有i≠1的点,prev[i]=v。
时间复杂度
外层主循环执行n-1次,内层循环执行n次,所以完成循环需要O(n^2)的时间复杂度。
添加涵爸微信,共同交流
~关于涵爸的介绍
标签一:奶爸(这是我最自豪的,没有之一)
8年奶爸生涯刚结束
新一轮奶爸生涯又开始
小二宝悄悄降临
笑声不断,欢乐无穷
标签二:编程高手(这是我给自己封的,有待认可)
才疏学浅,短见薄识
软件开发只有10多年的经验
掌握的C++和Java技能还不够出神入化
前端html、CSS、JS的娴熟度也不足百分
大数据、云计算、人工智能等也只略知一二
虚心万事能成,自满十事九空
涵爸愿虚心学习
不辜负此“高手”二字
标签三:老师(这是自己未来的定位,还需努力)
孩子的教育大于一切
于是我放弃了高薪
编程的普及大势所趋
于是我趟了这趟浑水
能力一般,水平有限
涵爸定当全力以赴
为大家分享最优质的信息
做出最专业的课堂
关注涵爸了解更多少儿编程知识。
以上是关于贪心算法(Dijkstra)解决单源最短路径问题(C++)的主要内容,如果未能解决你的问题,请参考以下文章