Dijkstra算法适用于解决有权图的单源最短路径问题,因此边的权重可以不同。Dijkstra算法通过维护一个优先队列来选择当前最短路径长度最小的顶点,并更新其邻居节点的最短路径长度。
Dijkstra算法步骤:
- 初始化:将源点到所有其他顶点的距离初始化为无穷大,源点到自身的距离初始化为0
- 选择最小距离顶点:从未访问的顶点中选择距离最小的顶点
- 更新邻居距离:更新选中顶点的所有邻居节点的最短路径长度
- 重复:重复步骤2和3,直到所有顶点都被访问过
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
const int MAX_VERTICES = 100; // 假设图中最多有100个顶点
const int INF = INT_MAX; // 用INT_MAX表示无穷大,即不可达的状态
// 邻接表表示的有权图
class WeightedGraph {
private:
int vertex_number; // 顶点的数量
std::vector<std::vector<std::pair<int, int>>> adjacency_table; // 邻接表,每一行存储边和权重
public:
// 构造函数,并将参数赋值给私有成员变量
WeightedGraph(int val) : vertex_number(val), adjacency_table(val) {
// 判断传入的顶点数是否超过最大顶点数
if (val > MAX_VERTICES) {
std::cout << "传入的顶点数已超过可接纳的最大顶点数,将导致程序终止!" << std::endl;
std::exit(EXIT_SUCCESS); // 终止程序
}
}
// 添加有向边,参数传入两个顶点和一个权重,顶点u指向顶点v,w为边的权重
void add_edge(int u, int v, int w) {
adjacency_table[u].push_back(std::make_pair(v, w));
}
// Dijkstra算法实现
std::vector<int> dijkstra(int src) {
std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> pq; // 创建优先队列
std::vector<int> dist(vertex_number, INF); // 存储从源点到每个顶点的距离
// 初始化源点
dist[src] = 0;
// 将源点加入优先队列
pq.push(std::make_pair(src, 0));
while (!pq.empty()) {
// 取出队首元素
int u = pq.top().first;
pq.pop();
// 遍历所有邻接顶点
for (const auto& i : adjacency_table[u]) {
int v = i.first; // 顶点
int weight = i.second; // 权重
// 如果找到了更短的路径,更新距离并将其加入优先队列
if (dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
pq.push(std::make_pair(v, dist[v]));
}
}
}
return dist;
}
};
int main() {
WeightedGraph g(7); // 实例化类对象
// 构建有向有权图
g.add_edge(0, 1, 2);
g.add_edge(0, 3, 1);
g.add_edge(1, 3, 3);
g.add_edge(1, 4, 10);
g.add_edge(2, 0, 4);
g.add_edge(2, 5, 5);
g.add_edge(3, 2, 2);
g.add_edge(3, 4, 2);
g.add_edge(3, 5, 8);
g.add_edge(3, 6, 4);
g.add_edge(4, 6, 1);
g.add_edge(6, 5, 1);
std::vector<int> distances = g.dijkstra(2); // 调用dijkstra算法
// 输出结果
std::cout << "Shortest paths from source vertex v3:\n";
for (int i = 0; i < distances.size(); i++) {
if (distances[i] == INT_MAX)
std::cout << "vertex v" << i + 1 << " \t\t Not reachable\n";
else
std::cout << "v" << i + 1 << " \t\t " << distances[i] << "\n";
}
return 0;
}
---------
Shortest paths from source vertex v3:
v1 4
v2 6
v3 0
v4 5
v5 7
v6 5
v7 8