BFS(宽度优先搜索):
运用队列,层序遍历,求最优的方案(不遍历所有结果,只求最短)
ps:状态有限,数有限才能使用
1.BFS模型
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
// 任务:求从1点开始,利用bfs遍历完这张图
vector<int> e[maxn];
int bk[maxn]; // 是否已经进入队列
queue<int> q; // 待扩展队列
int main()
{
int n , m; cin >> n >> m;
for (int i = 1 ; i <= m ; i++){
int x , y; cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
q.push(1);
bk[1] = 1;
// 正式进入bfs
while (q.size()){
int u = q.front();
cout << "现在我在" << u << "点,把他提出队列" << endl;
q.pop();
for (auto v : e[u]){
// 同时也保证了我们的最短路性质
if (bk[v]) // v 要么是跟我同级的,要么在我之前.
{
cout << "对于" << u << "来说" << v << "是没必要访问的" << endl;
continue;// 不管怎么样,都没必要访问了
}
cout << "对于" << u << "来说" << v << "是有必要访问的,放入队列!" << endl;
q.push(v);
bk[v] = 1;
}
}
return 0;
}
/*
5 6
1 2
1 3
2 3
3 4
3 5
4 5
*/
2.BFS应用
可以加pair或者结构体记录步长
1)单源最短路
ps:单点出发
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
// 任务:求从1点开始,利用bfs遍历完这张图
vector<int> e[maxn];
struct Node /*点*/
{
int g , step; // 点 , 距离
};
int dist[maxn];
int bk[maxn]; // 是否已经进入队列
queue<Node> q; // 待扩展队列
int main()
{
int n , m; cin >> n >> m;
for (int i = 1 ; i <= m ; i++){
int x , y; cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
q.push({1 , 0});
bk[1] = 1;
// 正式进入bfs
while (q.size()){
Node u = q.front();
dist[u.g] = u.step;
q.pop();
for (auto v : e[u.g]){
// 同时也保证了我们的最短路性质
if (bk[v]) // v 要么是跟我同级的,要么在我之前.
continue;// 不管怎么样,都没必要访问了
q.push({v , u.step + 1});
bk[v] = 1;
}
}
for (int i = 1 ; i<= n ; i++){
cout << dist[i] << " ";
}
cout << endl;
return 0;
}
/*
6 6
1 2
2 3
3 4
1 4
3 5
5 6
*/
2)多源最短路
ps:多点出发
加一个超级源点(虚点)
3)联通块
#include <bits/stdc++.h>
using namespace std;
vector<int> e[1000];
queue<int> q;
int bk[1000];
int main()
{
int n , m;
cin >> n >> m ;
for(int i = 1 ; i <= m ;i++){
int x , y ;
cin >> x >>y;
e[x].push_back(y);
e[y].push_back(x);
}
int ans=0;
for(int i = 1 ;i <= n ; i++){
if(bk[i]) continue;
q.push(i);
bk[i] = 1;
while(q.size()){
int u = q.front();
q.pop();
for(auto g:e[u]){
if(bk[g]) continue;
q.push(g);
bk[g] = 1;
}
}
ans++;
}
cout <<ans;
return 0;
}