[编程笔记]-Dijkstra(Plain)迪杰斯特拉(朴素版)

前言

与之前不同的是,图论的问题,重实现,而不重原理,所以这几篇博客会重点记录实现部分。

实现

  1. 初始化:设立一个集合S(空)储存所有已确定最短距离的点,并设立距离dis数组,除了起点设为0外,其他点都设为正无穷。
  2. 在所有点中,找一个不在S里并且dis最小的点t
  3. 把t加入集合S,并且更新所有与之相连的点的距离。
  4. 重复执行2、3步直到每个点都加入集合S

代码

update 2024/8/3: 新打了一份代码,在老代码下面,别急着走啊( •̀ ω •́ )✧

本来打算打一份邻接表/链式前向星,但只找到了邻接矩阵的代码,反正没差多少,就写了吧。

注:赶时间,所以只能交一份陈年老代码,马蜂混乱(~ ̄▽ ̄)~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h>
using namespace std;

int n,p,k,a,b,l;
int sz[505][505];
int dis[1005],vis[1005];

int main(){
cin>>n>>p;
memset(sz,-1,sizeof(sz));
for(int i=0;i<p;i++){
cin>>a>>b>>l;
if(sz[a][b]!=-1)sz[a][b]=min(sz[a][b],l);
else sz[a][b]=l;
}
for(int i=1;i<=n;i++)dis[i]=INT_MAX;
dis[1]=0;
while(true){
int mn=INT_MAX,mi=0;
for(int i=1;i<=n;i++){
if(dis[i]<mn&&!vis[i]){
mn=dis[i];
mi=i;
}
}
if(!mi)break;
vis[mi]=1;
for(int i=1;i<=n;i++){
if(sz[mi][i]!=-1&&dis[mi]+sz[mi][i]<dis[i]&&!vis[i]){
dis[i]=dis[mi]+sz[mi][i];
}
}
}
if(dis[n]==INT_MAX){
cout<<"-1";
return 0;
}
cout<<dis[n];
return 0;
}

新打了一份,照样是邻接矩阵,但是码风好看多了~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<bits/stdc++.h>
using namespace std;

const int N=505;

int n,m;
int g[N][N];
int x,y,z;

int dij(int be,int en){
bool fns[N]={false};
int dis[N];
memset(dis,0x3f,sizeof(dis));
dis[be]=0;
for(int i=0;i<n;i++){
int mi=-1;
for(int j=1;j<=n;j++){
if(!fns[j]&&(mi==-1||dis[j]<dis[mi]))mi=j;
}
fns[mi]=true;
if(mi==en)break;
for(int j=1;j<=n;j++){
dis[j]=min(dis[j],dis[mi]+g[mi][j]);
}
}
if(dis[en]==0x3f3f3f3f)return -1;
else return dis[en];
}

int main(){
cin>>n>>m;
memset(g,0x3f,sizeof(g));
while(m--){
cin>>x>>y>>z;
g[x][y]=min(g[x][y],z);
}
cout<<dij(1,n);
return 0;
}

完结撒花o( ̄︶ ̄)o


[编程笔记]-Dijkstra(Plain)迪杰斯特拉(朴素版)
http://githarlem.github.io/2024/08/03/Dijkstra-Plain/
作者
Harlem
发布于
2024年8月3日
更新于
2024年8月3日
许可协议