算法简介
算法用于求解源点到各个节点直接的最短路径。该算法的核心是使用路径松弛操作,借助一个三角不等式进行实现。
假设当前的的源点是
s
s
s,目的节点是
v
v
v,
δ
(
s
,
v
)
\delta(s,v)
δ(s,v)表示当前
s
s
s到
v
v
v的最短距离,
u
u
u表示
v
v
v的任意一个节点,而且
w
(
u
,
v
)
w(u,v)
w(u,v)表示边的权重,那么恒有:
δ
(
s
,
v
)
≤
δ
(
s
,
u
)
+
w
(
u
,
v
)
\delta(s,v)\le \delta(s,u)+w(u,v)
δ(s,v)≤δ(s,u)+w(u,v)
当且仅当
u
u
u是
s
s
s到
v
v
v的最短路上的节点时,等号成立。
算法的基本步骤
算法把节点分成2个集合,集合 S S S表示已经求出最短路的节点,结合 T T T表示需要求出最短路的节点。算法重复以下的步骤:
- 从 T T T中选出距离 S S S最近的节点
- 对选出的节点进行松弛操作:
并把选出的节点从 T 1 加 入 T1加入 T1加入S$if v.d > u.d + w(u, v) v.d = u.d + w(u ,v)
- 重复上述步骤,直到 T T T是空。
核心代码
#include <bits/stdc++.h>
using namespace std;
const int INF = 10000000;
const int MAXN = 1000;
int dist[MAXN], S[MAXN];
struct Node {
int v, int w;
Node (): v (0), w (0) {}
};
void Dijkstra (vector<vector<Node>>& graph,
vector<int>& path,
int src) {
int N = graph.size();
if (N <= 0) {
return;
}
for (int i = 0; i < N; ++i) {
dist[i] = INF;
S[i] = 0;
path.push_back (-1);
}
dist[src] = 0;
path[src] = -1;
S[src] = 1;
int M = graph[src].size();
for (int i = 0; i < M; ++i) { // 初始化距离
dist[graph[src][i].v] = graph[src][i].w;
}
for (int i = 0; i < N; ++i) {
int Min = INF, u = src;
for (int j = 0; j < N; ++j) { // 寻找最近的结点
if (!S[j] && dist[j] < Min) {
Min = dist[j];
u = j;
}
}
S[u] = 1;
for (auto& node : graph[u]) { // 路径调整
if (!S[node.v] && dist[u] + node.w < dist[node.v]) {
dist[node.v] = dist[u] + node.w;
path[node.v] = u;
}
}
}
}
int main() {
return 0;
}