适用范围
单源最短路、非负边权、连通图,顶点数最好小于5000
算法思想
总得来说就是,从源点开始找,找源点所有当前未确定顶点中距离估计值最小的顶点(并且该顶点没有被确定最短路径)(一开始肯定找源点自己,更新源点的出边),找到之后,标记这个顶点u,通过这个顶点u更新其他顶点到源点的距离,以此类推,每次都找dist[i]最小的那个顶点
代码
//Dijkstra朴素版
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e3 + 1;
const int inf = 1e9 + 7;
int n, m;
int edges[N][N];
int dist[N];
bool visited[N];
int c[N];
void addEdge(int edges[N][N], int u, int v, int w) {
edges[u][v] = min(w, edges[u][v]);
edges[v][u] = min(w, edges[v][u]);
}
//在没有确定到源点的最短路径的顶点中,也就是visited[i]==false时的顶点
int DijFindMin(int dist[N], bool visited[N], int n) {
int u = -1;
for (int i = 0; i < n; i++) {
//已经被访问或不可达
if (visited[i] || dist[i] == inf)continue;
if (u == -1 || dist[i] < dist[u]) {
u = i;
}
}
return u;
}
//通过找到的顶点u如果能更新则更新其他顶点到源点的距离
void DijUpdate(int dist[N], bool visited[N], int n, int u) {
for (int v = 0; v < n; v++) {
if (visited[v] || edges[u][v] == inf)continue;
dist[v] = min(dist[v], dist[u] + edges[u][v]);
}
}
void Dijkstra(int edges[N][N], int dist[N], bool visited[N], int n, int s) {
for (int i = 0; i < n; i++) {
dist[i] = inf, visited[i] = false;
}
dist[s] = 0;
while (1) {
int u = DijFindMin(dist, visited, n);
if (u == -1)break;
visited[u] = true;
DijUpdate(dist, visited, n, u);
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
edges[i][j] = inf;
}
}
for (int i = 0; i < n; i++)cin >> c[i];
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
addEdge(edges, u-1 , v-1 , w);
}
int s = 0;
Dijkstra(edges, dist, visited, n, s);
cout << dist[n-1];
return 0;
}