广度优先搜索(BFS)
宽搜适合于边权相同的最短路问题
宽搜基本框架
queue //放入初始状态
while(queue不空){
t = q[hh ++ ] //取出队头,弹出队头
q[++ tt] = ?? //拓展队尾
}
宽搜的过程:从根开始,向下逐层扩展,逐层访问
宽搜的实现:宽搜是通过队列实现的,用queue创建一个队列。宽搜的过程,通过队列来维护序列的状态空间,入队就排队等待,出队就扩展儿子们入队。
迷宫最短路
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 110;
typedef pair<int,int> PII;
int n,m;
int g[N][N];
int d[N][N];
PII q[N * N];
int bfs(){
int hh = 0,tt = 0;
q[0] = {0,0};
memset(d,-1,sizeof d);
d[0][0] = 0;
int dx[4] = {-1,1,0,0},dy[4] = {0,0,-1,1};
while(hh <= tt){
auto t = q[hh ++ ];
for(int i = 0;i < 4;i ++ ){
int x = t.first + dx[i],y = t.second + dy[i];
if(x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1){
d[x][y] = d[t.first][t.second] + 1;
q[ ++ tt] = {x,y};
}
}
}
return d[n - 1][m - 1];
}
int main(){
cin >> n >> m;
for(int i = 0;i < n;i ++ ){
for(int j = 0;j < m;j ++ ){
cin >> g[i][j];
}
}
cout << bfs() << endl;
return 0;
}
八数码难题
#include<iostream>
#include<cstring>
#include<unordered_map>
#include<queue>
using namespace std;
int bfs(string start){
unordered_map<string,int> d; //距离
queue<string> q;
q.push(start);
d[start] = 0;
int dx[4] = {-1,1,0,0},dy[4] = {0,0,-1,1};
string end = "12345678x";
while(q.size()){
string t = q.front();
q.pop();
if(t == end) return d[t];
//状态转移
int distance = d[t];
int k = t.find('x');
int x = k / 3,y = k % 3; //将一维数组下标转化为二维数组下标
for(int i = 0;i < 4;i ++ ){
int a = x + dx[i],b = y + dy[i];
if(a < 3 && a >= 0 && b < 3 && b >= 0){
swap(t[k],t[a * 3 + b]);
if(!d.count(t)){
d[t] = distance + 1;
q.push(t);
}
swap(t[k],t[a * 3 + b]);
}
}
}
return -1;
}
int main(){
char s[2];
string start;
for(int i = 0;i < 9;i ++ ){
cin >> s;
start += *s;
}
cout << bfs(start) << endl;
return 0;
}