单源最短路——dijkstra算法

时间:2023-03-08 23:38:17
单源最短路——dijkstra算法

定义概览

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。(单源最短路径)

算法描述

1)算法思想:

设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

2)算法步骤:

a.初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。

b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。

c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。

d.重复步骤b和c直到所有顶点都包含在S中。

执行动画过程如下图

单源最短路——dijkstra算法

动图太快可以看下面的例子:

aaarticlea/jpeg;base64,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" alt="" name="图片 1" width="345" height="204" align="bottom" border="0" hspace="1" />

单源最短路——dijkstra算法

重点需要理解这句拗口的”按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点vS中各顶点的最短路径长度不大于从源点vU中任何顶点的最短路径长度

实际上,Dijkstra 算法是一个排序过程,就上面的例子来说,是根据A到图中其余点的最短路径长度进行排序,路径越短越先被找到,路径越长越靠后才能被找到,要找A到F的最短路径,我们依次找到了 
A –> C 的最短路径 3 
A –> C –> B 的最短路径 5 
A –> C –> D 的最短路径 6 
A –> C –> E 的最短路径 7 
A –> C –> D –> F 的最短路径 9

为什么Dijkstra 算法不适用于带负权的图? 
就上个例子来说,当把一个点选入集合S时,就意味着已经找到了从A到这个点的最短路径,比如第二步,把C点选入集合S,这时已经找到A到C的最短路径了,但是如果图中存在负权边,就不能再这样说了。举个例子,假设有一个点Z,Z只与A和C有连接,从A到Z的权为50,从Z到C的权为-49,现在A到C的最短路径显然是A –> Z –> C

再举个例子:

单源最短路——dijkstra算法

在这个图中,求从A到C的最短路,如果用Dijkstra根据贪心的思想,选择与A最接近的点C,长度为7,以后不再变化。但是很明显此图最短路为5。归结原因是Dijkstra采用贪心思想,不从整体考虑结果,只从当前情况考虑选择最优。

4.代码模板

 #include<stdio.h>
#include<string.h>
#define inf 0x3f3f3f3f
int map[][],dis[],visit[];
/*
关于三个数组:map数组存的为点边的信息,比如map[1][2]=3,表示1号点和2号点的距离为3
dis数组存的为起始点与每个点的最短距离,比如dis[3]=5,表示起始点与3号点最短距离为5
visit数组存的为0或者1,1表示已经走过这个点。
*/
int n,m;
int dijstra()
{
int i,j,pos=,min,sum=;
memset(visit,,sizeof(visit));//初始化为.,表示开始都没走过
for(i=; i<=n; ++i)
{
dis[i]=map[][i];
}
visit[]=;
dis[]=;
for(i=; i<n; i++)
{
min=inf;
for(j=; j<=n; ++j)
{
if(visit[j]==&&min>dis[j])
{
min=dis[j];
pos=j;
}
}
visit[pos]=;//表示这个点已经走过
for(j=; j<=n; ++j)
{
if(visit[j]==&&dis[j]>dis[pos]+map[pos][j])//更新dis的值
dis[j]=dis[pos]+map[pos][j];
}
}
return dis[n];
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&m),n||m)//n表示n个点,m表示m条边
{
for(i=; i<=n; ++i)
{
for(j=; j<=n; ++j)
{
map[i][j]=inf;//开始时将每条边赋为最大值
}
}
int a,b,c;
for(i=; i<=m; ++i)
{
scanf("%d%d%d",&a,&b,&c);
if(c<map[a][b])//防止有重边
map[a][b]=map[b][a]=c;
}
int count=dijstra();
printf("%d\n",count);
}
return ;
}

邻接表实现:

 #include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int end;///终点
int power;///权值
} t;
int n;///n为点数
vector<node>q[];///邻接表储存图的信息
int dis[];///距离
int vis[];///标记数组
void Dijkstra(int start,int end)
{
int i,len,j,pos;
memset(vis,,sizeof(vis));
for(i=; i<=n; i++)
{
dis[i]=INF;
}
len=q[start].size();
for(i=; i<len; i++)
{
if(q[start][i].power<dis[q[start][i].end])
{
dis[q[start][i].end]=q[start][i].power;
}
}///从起点开始的dis数组更新
vis[start]=;
for(j=; j<n-; j++)
{
int pos,min=INF;
for(i=; i<=n; i++)
{
if(vis[i]!=&&dis[i]<min)
{
min=dis[i];
pos=i;///找到未访问节点中权值最小的
}
}
vis[pos]=;
len=q[pos].size();///再次更新dis数组
for(j=; j<len; j++)
{
if(vis[q[pos][j].end]==&&dis[q[pos][j].end]>q[pos][j].power+dis[pos])
{
dis[q[pos][j].end] = q[pos][j].power+dis[pos];
}
}
}
printf("%d\n",dis[end]);
}
int main()
{
int m,i;
int begin,end,power;
int a,b;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=; i<=n; i++)
{
q[i].clear();///将victor数组清空
}
for(i=; i<m; i++)
{
scanf("%d%d%d",&begin,&end,&power);///输入
t.end=end;
t.power=power;
q[begin].push_back(t);
t.end=begin;///无向图
t.power=power;
q[end].push_back(t);
}
scanf("%d%d",&a,&b);///输入起点与终点
Dijkstra(a,b);
}
return ;
}