宽度优先搜索是一种“盲目”搜索,所有结点的拓展都遵循“先进先出”的原则,所以采用“队列”来存储这些状态。宽度优先搜索的算法框架如下:
1、瓷砖
(queue写法)
#include<bits/stdc++.h>
using namespace std;
int px[4]={0,0,1,-1};
int py[4]={1,-1,0,0};
int main()
{ int h,w,a[60][60],i,j,ans=1,x,y;
char c;
queue <int> dx,dy;
cin>>h>>w;
for(i=1;i<=w;i++)
for(j=1;j<=h;j++)
{ cin>>c;
if(c=='.') a[i][j]=1;
if(c=='#') a[i][j]=0;
if(c=='@')
{ dx.push(i); dy.push(j);
a[i][j]=0;
}
}
while(!dx.empty())
{ for(i=0;i<4;i++)
{ x= dx.front()+px[i];
y= dy.front()+py[i];
if(a[x][y]==1)
{ ++ans;
dx.push(x); dy.push(y);
a[x][y]=0;
}
}
dx.pop(); dy.pop();
}
cout<<ans<<endl;
return 0;
}
(数组写法)
#include<bits/stdc++.h>
using namespace std;
int px[4]={0,0,1,-1};
int py[4]={1,-1,0,0};
int dx[200],dy[200];
int main()
{ int h,w,a[60][60],i,j,ans=1,x,y,head=0,tail=1;
char c;
cin>>h>>w;
for(i=1;i<=w;i++)
for(j=1;j<=h;j++)
{ cin>>c;
if(c=='.') a[i][j]=1;
if(c=='#') a[i][j]=0;
if(c=='@')
{ dx[1]=i; dy[1]=j;
a[i][j]=0;
}
}
while(head<=tail)
{ head++;
for(i=0;i<4;i++)
{ x= dx[head]+px[i];
y= dy[head]+py[i];
if(a[x][y]==1)
{ tail++;
++ans;
dx[tail]=x; dy[tail]=y;
a[x][y]=0;
}
}
}
cout<<ans<<endl;
return 0;
}
2、填涂颜色
#include<bits/stdc++.h>
using namespace std;
queue<int> dx,dy;
int py[2][4]={{-1,1,0,0},
{0,0,-1,1}};
int a[32][32]={};
int main()
{ int n,i,j,x=1,y=1;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) cin>>a[i][j];
dx.push(x);
dy.push(y);
while(!dy.empty())
{ for(i=0;i<4;i++)
{ x=dx.front()+py[0][i]; y=dy.front()+py[1][i];
// cout<<x<<" "<<y<<endl;
if(a[x][y]==0&&x>=0&&y>=0&&x<=n+1&&y<=n+1) { dx.push(x);dy.push(y); a[x][y]=2; }
}
dx.pop();dy.pop();
}
for(i=1;i<=n;i++)
{ for(j=1;j<=n;j++) cout<<2-a[i][j]<<" ";
cout<<endl;
}
}
3、求细胞数量
STL queue写法
#include<bits/stdc++.h>
using namespace std;
queue<int> dx,dy;
int py[2][4]={{-1,1,0,0},
{0,0,-1,1}};
int a[105][105]={},ans=0;
int n,m,i,j,x,y;
char c;
void bfs(int x,int y)
{ int X,Y;
ans++;
dx.push(x); dy.push(y);
a[x][y]=0;
while(!dy.empty())
{ for(int i=0;i<4;i++)
{ X=dx.front()+py[0][i]; Y=dy.front()+py[1][i];
if(a[X][Y]) { dx.push(X);dy.push(Y); a[X][Y]=0;}
}
dx.pop();dy.pop();
}
}
int main()
{ cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++) { cin>>c; a[i][j]=(c!='0'); }
for(i=1;i<=n;i++)
{ for(j=1;j<=m;j++)
if(a[i][j]) bfs(i,j);
}
cout<<ans;
}
数组写法
#include<bits/stdc++.h>
using namespace std;
int py[2][4]={{-1,1,0,0},
{0,0,-1,1}};
int a[105][105]={},ans=0;
int n,m,i,j,x,y;
int dx[100],dy[100];
char c;
void bfs(int x,int y)
{ int X,Y,head=0,tail=1;
ans++;
dx[1]=x; dy[1]=y;
a[x][y]=0;
while(head<=tail)
{ head++;
for(int i=0;i<4;i++)
{ X=dx[head]+py[0][i]; Y=dy[head]+py[1][i];
if(a[X][Y]) { tail++; dx[tail]=X;dy[tail]=Y; a[X][Y]=0;}
}
}
}
int main()
{ cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++) { cin>>c; a[i][j]=(c!='0'); }
for(i=1;i<=n;i++)
{ for(j=1;j<=m;j++)
if(a[i][j]) bfs(i,j);
}
cout<<ans;
}
4、面积(area)
5、关系网络
#include<bits/stdc++.h>
using namespace std;
int i,j,n,x,y,a[101][101],t=0;
queue <int> q;
queue <int > step;
int main()
{ cin>>n>>x>>y;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>a[i][j];
int b[101]={0};
q.push(x);
b[x]=1;
step.push(0);
while(!q.empty())
{ for(i=1;i<=n;i++)
{ if(a[q.front()][i]==1&& b[i]==0)
{ q.push(i);
step.push(step.front()+1);
if(i==y) { cout<<step.front(); return 0; }
b[i]=1;
}
}
q.pop();
step.pop();
}
}
用数组写
#include<bits/stdc++.h>
using namespace std;
int i,j,a[101][101];
int b[101],f[101],k[101];
int n,x,y,head=1,tail=1,tx;
int main()
{ cin>>n>>x>>y;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) cin>>a[i][j];
b[x]=1; f[1]=x; k[1]=0;
while(head<=tail)
{ tx=f[head];
if(tx==y) { cout<<k[head]-1; break;}
for(i=1;i<=n;i++)
{ if(a[tx][i]==1&& b[i]==0)
{ tail++;
f[tail]=i;
b[i]=1;
k[tail]=k[head]+1;
}
}
head++;
}
}
6、最少经过城市
用 queue 写
#include<bits/stdc++.h>
using namespace std;
int i,j,n,a[101][101],d[101]={0},f[101]={};
queue <int> q;
int out(int x){
if(x==0) return 0;
cout<<char(x+64);
if(f[x]!=0) cout<<"--";
return out(f[x]);
}
int main()
{ cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) cin>>a[i][j];
q.push(1);
d[1]=1;
while(!q.empty())
{ for(i=1;i<=n;i++)
if(a[q.front()][i]==0&&d[i]==0 )
{ q.push(i);
d[i]=1;
if(f[i]==0)f[i]=q.front();
if(i==n) out(n) ;
}
q.pop();
//for(i=1;i<=n;i++) cout<<f[i]<<" ";
//cout<<endl;
}
}
用数组写
#include<bits/stdc++.h>
using namespace std;
int i,j,n,a[101][101],d[101]={0},f[101]={};
int out(int x){
if(x==0) return 0;
cout<<char(x+64);
if(f[x]!=0) cout<<"--";
return out(f[x]);
}
int q[1001],tx;
int main()
{ cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) cin>>a[i][j];
d[1]=1;
int head=1,tail=1;
q[1]=1;
while(head<=tail)
{ tx=q[head];
for(i=1;i<=n;i++)
if(a[tx][i]==0&&d[i]==0 )
{ tail++;
q[tail]=i;
d[i]=1;
if(f[i]==0)f[i]=q[head];
if(i==n) out(n) ;
}
head++;
//for(i=1;i<=n;i++) cout<<f[i]<<" ";
//cout<<endl;
}
}
7、营救
#include<bits/stdc++.h>
using namespace std;
struct hhh
{ int h,l,s;//行,列,步数
}qwq[1000005];
int jz[1005][1005]={0},d[1005][1005]={0};
int main()
{ int bh[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int head,tail,ax,ay,bx,by,flag=0,n,nx,ny;
char ch;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{ getchar();getchar();
for(int j=1;j<=n;j++) jz[i][j]=getchar()-'0';
}
scanf("%d %d %d %d",&ax,&ay,&bx,&by);
head=1;tail=1;//队列初始化
qwq[tail].h=ax;
qwq[tail].l=ay;
qwq[tail].s=0;
tail++;
d[ax][ay]=1;
while(head<tail)
{ for(int i=0;i<4;i++)
{ nx=qwq[head].h+bh[i][0];
ny=qwq[head].l+bh[i][1];
if(nx<1||nx>n||ny<1||ny>n) continue;
if(jz[nx][ny]==0&& d[nx][ny]==0)
{ d[nx][ny]=1;
qwq[tail].h=nx;//入队
qwq[tail].l=ny;
qwq[tail].s=qwq[head].s+1;
tail++;
}
if(nx==bx&&ny==by) flag=1;break;
}
if(flag==1) break;
head++;//不管有没有新成员入队都要对已有的成员出队操作
}//tail指向队尾(最后一个元素的下一个位置,所以-1)
cout<<qwq[tail-1].s<<endl; return 0;
}