广度优先搜索(Breadth-First-Search,简称 BFS)。这是一种连通图的常用遍历策略,通常用于求起点到各点的最短路径,以及求两点之间的最优路径等问题。
广度优先搜索的主要操作如下:
-
选择图中任意一个顶点 v 作为起点进行访问,并将顶点 v 标为已访问。
-
遍历并访问与顶点 v 相邻且未被访问的所有顶点 c1, c2, …, ck,接着遍历并访问与顶点 c1, c2, ..., ck 相邻且未被访问的顶点,也就是依次访问所有相邻顶点的相邻顶点。以此类推,直到所有顶点均被访问。
结合队列先进先出的特性,我们可以借助它来具体实现广度优先搜索:
-
任意选择一个顶点 v 作为起点,加入队列。
-
访问队首元素 v 并标记,将其从队列中删除。
-
遍历与顶点 v 相邻且未被访问的所有顶点 c1, c2, …, ck,并依次加入到队列中。
-
重复第二步和第三步操作,直到队列为空。
具体实现代码如下:
此中,关于bfs function中有几处注意:#include <iostream> #include <vector> #include <cstring> #include <queue> using std::cin; using std::cout; using std::endl; using std::queue; using std::vector; class Graph { private: int n; bool *visited; vector<int> *edges; public: Graph(int input_n) { n = input_n; edges = new vector<int>[n]; visited = new bool[n]; memset(visited, 0, sizeof(bool) * n); } ~Graph() { delete[] edges; delete[] visited; } void insert(int x, int y){ edges[x].push_back(y); edges[y].push_back(x); } void bfs(int start_vertex){ queue<int> bfs_queue; bfs_queue.push(start_vertex); visited[start_vertex] = true; while (!bfs_queue.empty()) { int vertex = bfs_queue.front(); cout << vertex << endl; bfs_queue.pop(); for(int adj_vertex: edges[vertex]){ if(!visited[adj_vertex]){ bfs_queue.push(adj_vertex); visited[adj_vertex] = true; } } } } }; int main() { int n, m, k; cin >> n >> m; Graph g(n); for (int i = 0; i < m; ++i) { int x, y; cin >> x >> y; g.insert(x, y); } cin >> k; g.bfs(k); return 0; }
void bfs(int start_vertex){ queue<int> bfs_queue; bfs_queue.push(start_vertex); visited[start_vertex] = true; //1. while (!bfs_queue.empty()) { int vertex = bfs_queue.front(); cout << vertex << endl; bfs_queue.pop();
此中3号不能删除,否则会导致结点重复加入队列中以致重复遍历。//visited[vertex] = true 2. for(int adj_vertex: edges[vertex]){ if(!visited[adj_vertex]){ bfs_queue.push(adj_vertex); visited[adj_vertex] = true; //3. } } } }
且1号与2号可以任意选择,俩个位置都不影响。