写了几次dijkstra,但是还是总要查模板,这样下去不行,干脆自己写一个编码过程给自己看。别人爱不爱看无所谓啦
算法用途:计算单源最短路径
注意:
1.若起始节点改变,则需重新计算最短路
2.路径中不能出现负数
编码过程:
1.建立邻接矩阵(建立邻接表的我还不会)
将矩阵元素初始值设为INF,且矩阵中s[i][i]型的节点值设为0(顶点到它本身的路径为0)。当新路径小玉数组中已有路径时,更新路径。
有向图的邻接矩阵就不说了,无向图的邻接矩阵建立时要注意,每条边对应矩阵中两个数组元素(s[i][j]=s[j][i])。
2.设置标记数组vis[]与最短路数组dis[]
将vis[]数组初始值设为false,dis[]数组初始值设为起点v到各顶点i的路径(dis[i] = s[v][i])。由于之前建立邻接矩阵时已设置过初始值,因此两点之间无直接路径时dis[i] = INF。
标记起点(vis[v] = true)。
3.进行循环,计算起点到各点的最短路
循环的目的是将所有节点加入vis的集合。已加入集合的顶点,其标记数组对应值为true。因此循环时遍历标记数组值为false的点,每次选择其中离起点dis最小的一个(设为顶点u)加入vis集合。将顶点加入vis集合的操作进行n-1次(顶点v已在集合中不需再加入)。u加入vis集合后,起点v到各点的最短路发生改变,因此要再进行一次循环修改dis数组。
for(int i = 2; i <= n; ++i)//进行n-1次循环
{
int Min = INF;
int u;
for(int j = 1; j <= n; ++j)
{
if(!v[j] && dis[j] < Min)//顶点不在vis集合中
{
Min = dis[j];
u = j;
}
}//在vis集合以外的点中选择到顶点dis最小的点,将其加入vis集合
v[u]= true;
for(int k = 1; k <= n;++k)//更新dis数组
{
if(!v[k] && s[u][k] + Min < dis[k])
{
dis[k] = s[u][k]+ Min;
}
}
}
4.得到最短路
dis[i]就是起点到顶点i的最短路。