📜  未加权图 bfs 中的最短路径 - C++ (1)

📅  最后修改于: 2023-12-03 14:55:24.890000             🧑  作者: Mango

未加权图 BFS 中的最短路径 - C++

简介

在无权图中找到两个点之间的最短路径可以使用广度优先搜索(BFS)算法。BFS的本质是按照图的层级遍历,即从起点开始,依次遍历与其相邻的节点,然后遍历与这些节点相邻的节点,直到找到目标节点或搜索完整个图。由于在无权图中,所有边的权重都是一样的,因此从起点到目标节点的最短路径即为BFS的结果。

代码实现
#include<bits/stdc++.h>
using namespace std;

vector<int> adj[10001]; // 存储邻接表

int BFS(int start, int end){ // start表示起点, end表示终点
    vector<bool> visited(10001, false); // 标记数组,记录每个节点是否被访问过
    queue<pair<int,int>> q; // 存储当前节点和到该节点的距离
    q.push({start, 0}); // 将起点和距离push到队列中
    visited[start] = true; // 将起点标记为已访问
    while(!q.empty()){
        int curr = q.front().first; // 取出队首节点
        int dist = q.front().second; // 取出到该节点的距离
        q.pop(); // 将队首节点弹出
        if(curr == end){ // 如果当前节点是终点,即找到了最短路径
            return dist; // 返回到该节点的距离,即最短路径长度
        }
        for(int i=0; i<adj[curr].size(); i++){ // 遍历与当前节点相邻的节点
            int next = adj[curr][i]; // 取出相邻节点
            if(!visited[next]){ // 如果该相邻节点未被访问过
                visited[next] = true; // 将其标记为已访问
                q.push({next, dist+1}); // 将其push到队列中,并记录到该节点的距离
            }
        }
    }
    return -1; // 没找到终点,返回-1
}

int main(){
    int n, m, start, end;
    cin >> n >> m >> start >> end;
    for(int i=0; i<m; i++){
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v); // 构建邻接表
        adj[v].push_back(u);
    }
    int shortest_path = BFS(start, end); // 调用BFS算法求最短路径长度
    cout << shortest_path << endl;
    return 0;
}
解释
  • 首先定义一个邻接表,来表示整张图的节点和边的关系
  • 然后定义一个visited数组,用于记录每个节点是否被访问过,初值设为false
  • 再定义一个队列,用于存储当前节点和到该节点的距离,初值为起点和0
  • 将起点标记为已访问,然后开始BFS
  • 每次从队列中取出队首节点,判断是否为终点,如果是则返回到该节点的距离,即最短路径长度
  • 如果不是,则遍历与该节点相邻的节点,如果该节点未被访问过,则将其标记为已访问,并将其push到队列中,同时记录到该节点的距离(距离加1)
  • 最后,如果没有找到终点,则返回-1
总结

BFS算法在解决无权图中的最短路径问题时表现出色,时间复杂度为O(n+m),其中n表示节点数,m表示边数。在实际应用中,可以通过修改邻接表来处理不同的图,例如有向图、带权图等。