#写在前面
bfs能求出 所有边权==1 的 单源最短路问题 的证明
(可以看成是特殊的djikstra)

##走迷宫
----c++版
https://www.acwing.com/problem/content/description/846/
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=110;
typedef pair<int, int> PLL;
int n,m;
int g[N][N];
int d[N][N];
PLL 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,0,1,0},dy[4]={0,1,0,-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();
return 0;
}
##迷宫问题
https://www.acwing.com/problem/content/1078/
记录路径
----c++版
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define x first
#define y second
const int N=1010;
typedef pair<int, int> pll;
int n;
int g[N][N];
pll q[N*N];
pll pre[N][N];
void bfs(int sx, int sy){
int hh=0, tt=0;
q[0]={sx, sy};
int dx[4]={-1, 0, 1, 0}, dy[4]={0, 1, 0, -1};
memset(pre, -1, sizeof pre);
pre[sx][sy]={0, 0};
while(hh<=tt){
pll t=q[hh++];
for(int i=0; i<4; i++){
int a=t.x+dx[i], b=t.y+dy[i];
if(a<0||a>=n||b<0||b>=n)continue;
if(g[a][b])continue;
if(pre[a][b].x!=-1)continue;
q[++tt]={a, b};
pre[a][b]=t;
}
}
}
int main(){
scanf("%d", &n);
for(int i=0; i<n;i++)
for(int j=0; j<n; j++)
scanf("%d", &g[i][j]);
bfs(n-1, n-1);//从尾搜,在从头找路径,贪心
pll end(0, 0);
while(true){
printf("%d %d\n", end.x, end.y);
if(end.x==n-1&& end.y==n-1)break;
end = pre[end.x][end.y];
}
return 0;
}
##武士风度的牛
https://www.acwing.com/problem/content/190/
----c++版
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define x first
#define y second
//注意这题是先输入列数再输入行数
const int N=155;
typedef pair<int, int> pll;
int n,m;
char g[N][N];
pll q[N*N];
int dist[N][N];
int bfs(){
int dx[8]={-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8]={1, 2, 2, 1, -1, -2, -2, -1};
int sx, sy;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(g[i][j]=='K')
sx=i, sy=j;
int hh=0, tt=0;
q[0]={sx, sy};
memset(dist, -1, sizeof dist);
dist[sx][sy]=0;
while(hh<=tt){
auto t=q[hh++];
for(int i=0; i<8; i++){
int a=t.x+dx[i], b=t.y+dy[i];
if(a<0|| a>=n|| b<0 ||b>=m)continue;
if(g[a][b]=='*')continue;
if(dist[a][b]!=-1)continue;
if(g[a][b]=='H')return dist[t.x][t.y]+1;
dist[a][b]=dist[t.x][t.y]+1;
q[++tt]={a, b};
}
}
return -1;
}
int main(){
cin>>m>>n;//注意这里蛋疼的输入
for(int i=0; i<n; i++)cin>>g[i];
cout<<bfs()<<endl;
return 0;
}
##抓住那头牛
https://www.acwing.com/problem/content/1102/
----c++版
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define x first
#define y second
//直观上看,M直接开一百万
const int N=2e5+10;
int n,k;
int q[N];
int dist[N];
int bfs(){
memset(dist, -1, sizeof dist);
dist[n]=0;
q[0]=n;
int hh=0, tt=0;
while(hh<=tt){
int t=q[hh++];
if(t==k)return dist[k];
if(t+1<N&&dist[t+1]==-1){
dist[t+1]=dist[t]+1;
q[++tt]=t+1;
}
if(t-1>=0&&dist[t-1]==-1){
dist[t-1]=dist[t]+1;
q[++tt]=t-1;
}
if(t*2<N&&dist[t*2]==-1){
dist[t*2]=dist[t]+1;
q[++tt]=t*2;
}
}
return -1;
}
int main(){
cin>>n>>k;
cout<<bfs()<<endl;
return 0;
}
本文介绍了使用广度优先搜索(BFS)解决单源最短路径问题的方法,并通过四个实例详细展示了如何用C++实现这一算法。这些实例包括走迷宫、迷宫问题中的路径记录、武士风度的牛中骑士的移动以及寻找丢失的牛。

2034

被折叠的 条评论
为什么被折叠?



