C++ 图论实战:深入理解三种经典最短路径算法
最短路径问题是图论中的核心议题,旨在从带权有向图中找到两点间权值总和最小的路径。在实际工程中,根据图的特性(如是否存在负权边)和计算需求(单源或全源),我们需要选择合适的算法。
Dijkstra 算法:非负权图的贪心策略
Dijkstra 是解决单源最短路径的经典算法,采用贪心思想。它仅适用于没有负权边的图。算法维护一个已确定最短路径的集合,每次从未确定的节点中选出距离起点最近的点,用它去松弛邻接点的距离估计值,直到所有节点都被处理。

实现时需要注意初始化距离数组为无穷大,并将起点的距离设为 0。松弛操作是核心:如果 dist[u] + weight(u, v) < dist[v],则更新 v 的距离和前驱节点。
// src 是选定的起点,dist 记录起点到各点的最短路径,pPath 记录前驱顶点下标
void Dijkstra(const V& src, vector<W>& dist, vector<int>& pPath) {
size_t srci = GetVertexIndex(src);
size_t n = _vertexs.size();
// 初始化距离和前驱
dist.resize(n, MAX_W);
pPath.resize(n, -1);
dist[srci] = 0;
pPath[srci] = srci;
// S 标记已确定最短路径的顶点集合
vector<bool> S(n, false);
for (size_t j = 0; j < n; ++j) {
// 1. 在未确定集合中选距离最小且未访问的节点 u
int u = 0;
W min_dist = MAX_W;
for (size_t i = 0; i < n; ++i) {
if (!S[i] && dist[i] < min_dist) {
u = i;
min_dist = dist[i];
}
}
S[u] = ;
( v = ; v < n; ++v) {
(!S[v] && _matrix[u][v] != MAX_W && dist[u] + _matrix[u][v] < dist[v]) {
dist[v] = dist[u] + _matrix[u][v];
pPath[v] = u;
}
}
}
}



