Dijkstra算法流程(适合掌握思想但是不会写代码的人阅读)
因为看了其他博主的一篇博客写的Dijkstra算法,他的算法有点小问题,所以干脆自己写个博客,记录一下debug一个小时的艰辛历程。
算法流程
第一步 建立邻接矩阵Map[N][N](邻接表)标记数组vis[N]用来标记元素是否成为定点 dis[N]表示到源点的距离
第二步 初始化第一步中的数组
第三步 通过(!vis[j]&&Map[Mindex][j]+dis[Mindex]<dis[j])这个条件修改dis数组,dis[终点]就是要求的值
解释全写在代码的注释里,如果想了解代码思想的大佬可以去这篇博客看一下,不过他的代码有点小瑕疵
(!vis[j]&&Map[Mindex][j]+dis[Mindex]<dis[j])这个条件他漏掉了条件!vis[j]
但是他的图解和思路很清晰
[https://blog.csdn.net/lbperfect123/article/details/84281300]
第一步建表
#include <iostream>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
int Map[2505][2505];
int dis[2505];
int vis[2505];
第二步初始化
int n,m,Start,End;
cin >> n >> m >> Start >> End;//n表示点的个数,m表示边的个数,Start是起点,End是终点
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){//到自己的距离设为0,其他的设为无穷大
if(i==j)
Map[i][j]=0;
else
Map[i][j]=INF;
}
}
int s,t,w;//s起点,t终点,w权值
for(int i=0;i<m;i++){
cin >> s >> t >> w;
if(Map[s][t]>w){//因为两点之间可能有多条路,我们肯定要取最短的那条
Map[s][t] = w;
Map[t][s] = w;
}
}
for(int i=1;i<=n;i++){//先将dis数组中和源点有边相连的点设成边长,不直接相连的设成无穷大
dis[i] = Map[Start][i];
}
memset(vis,0,sizeof(vis));
vis[Start] = 1;
第三步,修改dis数组的值
for(int i=1;i<n;i++){//遍历n-1次,把除了源点的其他点都标记才结束
int Min = INF,Mindex;
for(int j=1;j<=n;j++){//从未标记的数组中找到最小值的下标
if(!vis[j]&&dis[j]<Min){
Mindex = j;
Min = dis[j];
}
}
vis[Mindex] = 1;//将最小值的下标加入标记
for(int j=1;j<=n;j++){
if(!vis[j]&&Map[Mindex][j]+dis[Mindex]<dis[j])//如果能以此次标记的点为桥梁,让未标记的点到源点的距离变短
//那么未标记的点到源点的距离修改为此次标记的点到源点的距离加此次标记的点到未标记的点的距离
dis[j] = Map[Mindex][j]+dis[Mindex];
}
}
cout <<dis[End];//输出dis[终点]即可
完整代码
#include <iostream>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
int Map[2505][2505];
int dis[2505];
int vis[2505];
int n,m,Start,End;
void Init(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)
Map[i][j]=0;
else
Map[i][j]=INF;
}
}
int s,t,w;
for(int i=0;i<m;i++){
cin >> s >> t >> w;
if(Map[s][t]>w){
Map[s][t] = w;
Map[t][s] = w;
}
}
for(int i=1;i<=n;i++){
dis[i] = Map[Start][i];
}
memset(vis,0,sizeof(vis));
vis[Start] = 1;
}
void Dijkstra(){
for(int i=1;i<n;i++){
int Min = INF,Mindex;
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]<Min){
Mindex = j;
Min = dis[j];
}
}
vis[Mindex] = 1;
for(int j=1;j<=n;j++){
if(!vis[j]&&Map[Mindex][j]+dis[Mindex]<dis[j])
dis[j] = Map[Mindex][j]+dis[Mindex];
}
}}
int main()
{
cin >> n >> m >> Start >> End;
Init();
Dijkstra();
cout <<dis[End];
}