单源BFS
P1746 离开中山路
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
const int N=1005;
char a[N][N];
queue<pair<int,int>>q;
// int flag[N][N]; //或者不用memset,用flag标记判断
int n,x1,y1,x2,y2;
int fx[]={-1,0,0,1};
int fy[]={0,-1,1,0};
int dis[N][N];
void bfs(int x1,int y1){
memset(dis,-1,sizeof dis);
dis[x1][y1]=0;
q.push({x1,y1});
// flag[x1][y1]=1;
while(q.size()){
if(dis[x2][y2]>=0) return; //提前终止
auto t=q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=t.first+fx[i];
int ny=t.second+fy[i];
if(nx<=0||nx>n||ny<=0||ny>n) continue;
// if(flag[nx][ny]==1) continue;
if(dis[nx][ny]>=0) continue;
if(a[nx][ny]=='1') continue;
dis[nx][ny]=dis[t.first][t.second]+1;
// flag[nx][ny]=1;
q.push({nx,ny});
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
scanf("%s",a[i]+1);
cin>>x1>>y1>>x2>>y2;
bfs(x1,y1);
cout<<dis[x2][y2]<<endl;
return 0;
}
P1443 马的遍历
Version 1——队列
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
const int N=405;
int a[N][N],dis[N][N];
queue<pair<int,int>>q;
int n,m,x,y;
int fx[]={-2,-2,-1,-1,1,1,2,2};
int fy[]={-1,1,-2,2,-2,2,-1,1};
void bfs(int x,int y){
memset(dis,-1,sizeof dis);
q.push({x,y});
dis[x][y]=0;
while(q.size()){
auto t=q.front();
q.pop();
for(int i=0;i<8;i++){
int nx=t.first+fx[i];
int ny=t.second+fy[i];
if(nx<1||nx>n||ny<1||ny>m) continue;
if(dis[nx][ny]>=0) continue;
dis[nx][ny]=dis[t.first][t.second]+1;
q.push({nx,ny});
}
}
}
int main(){
cin>>n>>m>>x>>y;
bfs(x,y);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%-5d",dis[i][j]);
}
printf("\n");
}
return 0;
}
Version 2——数组模拟队列
#include<iostream>
#include<string.h>
using namespace std;
const int N=405;
typedef pair<int,int> PII;
PII q[N*N];
int a[N][N],dis[N][N];
int hh=-1,tt;
int n,m,x,y;
int fx[]={-2,-2,-1,-1,1,1,2,2};
int fy[]={-1,1,-2,2,-2,2,-1,1};
void bfs(int x,int y){
memset(dis,-1,sizeof dis);
q[++hh]={x,y};
dis[x][y]=0;
while(hh<=tt){
auto t=q[hh++];
for(int i=0;i<8;i++){
int nx=t.first+fx[i];
int ny=t.second+fy[i];
if(nx<1||nx>n||ny<1||ny>m) continue;
if(dis[nx][ny]>=0) continue;
dis[nx][ny]=dis[t.first][t.second]+1;
q[++tt]={nx,ny};
}
}
}
int main(){
cin>>n>>m>>x>>y;
bfs(x,y);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%-5d",dis[i][j]);
}
printf("\n");
}
return 0;
}
多源BFS
P1332 血色先锋队
注意此题为四连通~
Version 1——初版未优化
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
const int N=505;
int n,m,a,b;
int dis[N][N];
queue<pair<int,int>>q,qlord;
// int fx[]={-1,-1,-1,0,0,1,1,1};
// int fy[]={-1,0,1,-1,1,-1,0,1};
int fx[]={-1,0,0,1};
int fy[]={0,-1,1,0};
void bfs(int x,int y){
while(q.size()){
auto t=q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=t.first+fx[i];
int ny=t.second+fy[i];
if(nx<1||nx>n||ny<1||ny>m) continue;
if(dis[nx][ny]>=0) continue;
dis[nx][ny]=dis[t.first][t.second]+1;
q.push({nx,ny});
}
}
}
int main(){
cin>>n>>m>>a>>b;
int x,y,startx,starty;
memset(dis,-1,sizeof dis);
cin>>x>>y;
dis[x][y]=0;
q.push({x,y});
startx=x;
starty=y;
for(int i=2;i<=a;i++){
cin>>x>>y;
dis[x][y]=0;
q.push({x,y});
}
bfs(startx,starty);
// for(int i=1;i<=b;i++){
// cin>>x>>y;
// cout<<dis[x][y]<<endl;
// }
for(int i=1;i<=b;i++){
cin>>x>>y;
qlord.push({x,y});
}
while(qlord.size()){
auto t=qlord.front();
qlord.pop();
cout<<dis[t.first][t.second]<<endl;
}
return 0;
}
Version 2——优化版本(更规范)
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
const int N=505;
int n,m,a,b;
int dis[N][N];
queue<pair<int,int>>q;
int fx[]={-1,0,0,1};
int fy[]={0,-1,1,0};
void bfs(){
while(q.size()){
auto t=q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=t.first+fx[i];
int ny=t.second+fy[i];
if(nx<1||nx>n||ny<1||ny>m) continue;
if(dis[nx][ny]>=0) continue;
dis[nx][ny]=dis[t.first][t.second]+1;
q.push({nx,ny});
}
}
}
int main(){
cin>>n>>m>>a>>b;
int x,y;
memset(dis,-1,sizeof dis);
for(int i=1;i<=a;i++){
cin>>x>>y;
dis[x][y]=0;
q.push({x,y});
}
bfs();
for(int i=1;i<=b;i++){
cin>>x>>y;
cout<<dis[x][y]<<endl;
}
return 0;
}
Version 3——数组模拟队列
方法同P1443,此处就不写了~