有向有权图的单源最短路径算法实现(Dijkstra)

Dijkstra算法适用于解决有权图的单源最短路径问题,因此边的权重可以不同。Dijkstra算法通过维护一个优先队列来选择当前最短路径长度最小的顶点,并更新其邻居节点的最短路径长度。

Dijkstra算法步骤:

  1. 初始化:将源点到所有其他顶点的距离初始化为无穷大,源点到自身的距离初始化为0
  2. 选择最小距离顶点:从未访问的顶点中选择距离最小的顶点
  3. 更新邻居距离:更新选中顶点的所有邻居节点的最短路径长度
  4. 重复:重复步骤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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值