有向无权图的单源最短路径算法实现

在无权图中,单源最短路径问题通常可以通过广度优先搜索(BFS)算法来解决。BFS是一种基于队列的图遍历算法,它从源点开始,逐层扩展,直到找到目标节点或遍历完所有节点。由于无权图中所有边的权重相同,BFS能够保证找到的路径是最短的。

BFS算法的时间复杂度为O(V+E),其中V是图中顶点的数量,E是边的数量。由于BFS访问每个顶点和边的次数最多为一次,因此在无权图中效率较高。

BFS算法步骤:

  1. 初始化:创建一个队列,将源点入队,同时标记源点为已访问
  2. 层序遍历:从队列中取出一个节点,访问它的所有未访问的邻居节点。如果邻居节点未被访问过,则将其标记为已访问,并将其加入队列
  3. 重复:重复步骤2,直到队列为空或找到目标节点
  4. 路径重建:通过记录每个节点的前驱节点,可以从目标节点回溯到源节点,重建最短路径

在这里插入图片描述

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>


const int MAX_VERTICES = 100;  // 假设图中最多有100个顶点
const int INF = INT_MAX;  // 用INT_MAX表示无穷大,即不可达的状态


// 邻接表表示的无权图
class UnweightedGraph {
private:
    int vertex_number;  // 顶点的数量
    std::vector<std::vector<int>> adjacency_table;  // 邻接表

public:
    // 构造函数,并将参数赋值给私有成员变量
    UnweightedGraph(int val) : vertex_number(val), adjacency_table(val) {
        // 判断传入的顶点数是否超过最大顶点数
        if (val > MAX_VERTICES) {
            std::cout << "传入的顶点数已超过可接纳的最大顶点数,将导致程序终止!" << std::endl;
            std::exit(EXIT_SUCCESS);  // 终止程序
        }

        // 查看邻接表的初始值,并无实际意义,可注释掉
        for (int i = 0; i < adjacency_table.size(); ++i) {
            for (auto value : adjacency_table[i]) {
                std::cout << value << " ";
            }
            std::cout << std::endl;
        }
    }

    // 添加有向边,参数传入两个顶点,顶点v指向顶点w
    void add_edge(int v, int w) {
        adjacency_table[v].push_back(w);
    }

    // BFS算法实现
    void bfs(int src) {
        std::queue<int> q;  // 创建队列
        std::vector<int> dist(vertex_number, INF);  // 存储从源点到每个顶点的距离
        std::vector<bool> visited(vertex_number, false);  // 标记顶点是否已访问

        // 初始化源点
        dist[src] = 0;

        // 将源点加入队列,并标记为已访问
        q.push(src);
        visited[src] = true;

        while (!q.empty()) {
            // 取出队首元素
            int v = q.front();
            q.pop();

            // 遍历所有邻接顶点
            for (int neighbor : adjacency_table[v]) {
                if (!visited[neighbor]) {
                    dist[neighbor] = dist[v] + 1;  // 更新距离
                    q.push(neighbor);
                    visited[neighbor] = true;
                }
            }
        }

        // 输出结果
        for (int i = 0; i < vertex_number; i++) {
            if (dist[i] == INF)
                std::cout << "Vertex v" << i+1 << " is not reachable from source\n";
            else
                std::cout << "Shortest path to vertex v" << i+1 << " is " << dist[i] << " edges away\n";
        }
    }
};


int main() {
    UnweightedGraph g(8);  // 实例化类对象

    // 构建有向无权图
    g.add_edge(0, 1);
    g.add_edge(0, 3);
    g.add_edge(1, 3);
    g.add_edge(1, 4);
    g.add_edge(2, 0);
    g.add_edge(2, 5);
    g.add_edge(3, 2);
    g.add_edge(3, 4);
    g.add_edge(3, 5);
    g.add_edge(3, 6);
    g.add_edge(4, 6);
    g.add_edge(6, 5);

    std::cout << "Shortest paths from source vertex v3:\n";
    g.bfs(2);  // 调用bfs算法

    return 0;
}
---------
Shortest paths from source vertex v3:
Shortest path to vertex v1 is 1 edges away
Shortest path to vertex v2 is 2 edges away
Shortest path to vertex v3 is 0 edges away
Shortest path to vertex v4 is 2 edges away
Shortest path to vertex v5 is 3 edges away
Shortest path to vertex v6 is 1 edges away
Shortest path to vertex v7 is 3 edges away
Vertex v8 is not reachable from source

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值