广度优先搜索BFS
广度优先搜索BFS
必须学习过队列、结构体(pair)才能够学广度优先搜索
B3625 迷宫寻路
可以让学生用深搜做一遍,复习一下深搜
然后讲广搜
1 //深搜 60分 2 #include<iostream> 3 #include<queue> 4 using namespace std; 5 int n,m,flag; 6 char a[110][110]; 7 int dx[5]= {0,-1,0,1,0}; 8 int dy[5]= {0,0,1,0,-1}; 9 void dfs(int x,int y) { 10 if(flag) return; 11 if(x==n&&y==m) { 12 flag=1; 13 return; 14 } 15 for(int i=1; i<=4; i++) { 16 int nx=x+dx[i]; 17 int ny=y+dy[i]; 18 if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]=='.') { 19 a[nx][ny]='#'; 20 dfs(nx,ny); 21 a[nx][ny]='.'; 22 } 23 } 24 return; 25 } 26 int main() { 27 cin>>n>>m; 28 for(int i=1; i<=n; i++) { 29 for(int j=1; j<=m; j++) { 30 cin>>a[i][j]; 31 } 32 } 33 dfs(1,1); 34 if(flag) cout<<"Yes"<<endl; 35 else cout<<"No"<<endl; 36 return 0; 37 }
1 //广搜 100分 2 #include<iostream> 3 #include<queue> 4 #include<utility> 5 using namespace std; 6 typedef pair<int,int> pii; 7 pii a,b; 8 int n,m,flag; 9 char c[110][110]; 10 int dx[5]= {0,-1,0,1,0}; 11 int dy[5]= {0,0,1,0,-1}; 12 void bfs(int x,int y) { 13 queue<pii> q; 14 a.first=x; 15 a.second=y; 16 q.push(a); 17 while(!q.empty()) { 18 a=q.front(); 19 q.pop(); 20 for(int i=1; i<=4; i++) { 21 int nx=a.first+dx[i]; 22 int ny=a.second+dy[i]; 23 if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&c[nx][ny]=='.') { 24 b.first=nx; 25 b.second=ny; 26 if(nx==n&&ny==m) { 27 flag=1; 28 return; 29 } 30 q.push(b); 31 c[nx][ny]='#'; 32 } 33 } 34 } 35 return; 36 } 37 int main() { 38 cin>>n>>m; 39 for(int i=1; i<=n; i++) { 40 for(int j=1; j<=m; j++) { 41 cin>>c[i][j]; 42 } 43 } 44 bfs(1,1); 45 if(flag) cout<<"Yes"<<endl; 46 else cout<<"No"<<endl; 47 return 0; 48 }
B3626 跳跃机器人
//B3626 跳跃机器人 #include<iostream> #include<cstring> #include<queue> using namespace std; int n; int vis[1000010]; queue<int> q; void bfs() { memset(vis,-1,sizeof vis); q.push(1); vis[1]=0; while(!q.empty()) { int t=q.front(); q.pop(); if(t==n) { cout<<vis[n]; return; } if(t-1>=1&&t-1<=n&&(vis[t-1]>vis[t]+1||vis[t-1]==-1)) { //t-1 q.push(t-1); vis[t-1]=vis[t]+1; } if(t+1>=1&&t+1<=n&&(vis[t+1]>vis[t]+1||vis[t+1]==-1)) { //t+1 q.push(t+1); vis[t+1]=vis[t]+1; } if(2*t>=1&&2*t<=n&&(vis[2*t]>vis[t]+1||vis[2*t]==-1)) { //t-1 q.push(2*t); vis[2*t]=vis[t]+1; } } return; } int main() { cin>>n; bfs(); return 0; }
P1443 马的遍历
#include<iostream> #include<queue> #include<utility> using namespace std; typedef pair<int,int> pii; pii a,b; int n,m,flag; int c[410][410]; int dx[8]= {-1,-2,-2,-1,1,2,2,1}; int dy[8]= {2,1,-1,-2,2,1,-1,-2}; //8个方向 void bfs(int x,int y) { queue<pii> q; a.first=x; a.second=y; q.push(a); while(!q.empty()) { a=q.front(); q.pop(); for(int i=0; i<8; i++) { int nx=a.first+dx[i]; int ny=a.second+dy[i]; if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&c[nx][ny]==-1) { b.first=nx; b.second=ny; q.push(b); c[nx][ny]=c[a.first][a.second]+1; } } } return; } int main() { int x,y; cin>>n>>m>>x>>y; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { c[i][j]=-1; } } c[x][y]=0; bfs(x,y); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { printf("%5d",c[i][j]); } cout<<endl; } return 0; }
P2802 回家
//P2802 回家 #include<cstdio> #include<iostream> #include<queue> #include<cstring> using namespace std; const int N=15; int n,m,sx,sy,f=1; int g[N][N]; int vis[N][N];//记录血量 int dx[]= {0,0,-1,1}; int dy[]= {-1,1,0,0}; struct nodes { int x,y,ti; } t; void bfs() { memset(vis,-1,sizeof vis); queue<nodes> q; q.push({sx,sy,0}); vis[sx][sy]=6; while(!q.empty()) { t=q.front(); q.pop(); if(g[t.x][t.y]==3&&vis[t.x][t.y]!=0) { //到家了 cout<<t.ti; f=0; return; } if(g[t.x][t.y]==4) vis[t.x][t.y]=6;//补血 if(vis[t.x][t.y]>1) {//血量必须大于1才能继续往下走 for(int i=0; i<4; i++) { int xx=t.x+dx[i]; int yy=t.y+dy[i]; if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&g[xx][yy]!=0&&vis[t.x][t.y]-1>=vis[xx][yy]) { vis[xx][yy]=vis[t.x][t.y]-1; q.push({xx,yy,t.ti+1}); } } } } } int main() { cin>>n>>m; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { cin>>g[i][j]; if(g[i][j]==2) { sx=i; sy=j; } } } bfs(); if(f) cout<<-1; return 0; }
P3958 [NOIP2017 提高组] 奶酪
//P3958 [NOIP2017 提高组] 奶酪 #include<cstdio> #include<iostream> #include<queue> #include<cstring> using namespace std; long long T,n,h,r; long long x[1010],y[1010],z[1010],vis[1010]; struct nodes { long long x,y,z; } t; queue<nodes> q; bool dis(int i,nodes u) { long long xx=x[i]-u.x; long long yy=y[i]-u.y; long long zz=z[i]-u.z; return xx*xx+yy*yy+zz*zz<=4*r*r; } int main() { scanf("%lld",&T); while(T--) { memset(vis,0,sizeof vis); scanf("%lld %lld %lld",&n,&h,&r); for(int i=1; i<=n; i++) { scanf("%lld %lld %lld",&x[i],&y[i],&z[i]); if(z[i]-r<=0) { //入口 q.push({x[i],y[i],z[i]}); vis[i]=1; } } int f=1; while(!q.empty()) { t=q.front(); q.pop(); if(t.z+r>=h) { printf("Yes\n"); f=0; break; } for(int i=1; i<=n; i++) { if(!vis[i]&&dis(i,t)) { q.push({x[i],y[i],z[i]}); vis[i]=1; } } } if(f) printf("No\n"); while(!q.empty()) q.pop(); } return 0; }
P3956 [NOIP2017 普及组] 棋盘
//P3956 [NOIP2017 普及组] 棋盘 #include<cstdio> #include<iostream> #include<queue> #include<cstring> using namespace std; const int N=1010; int n,m,x,y,c,ans=N*N*2; int g[N][N],vis[N][N]; int dx[]= {0,0,1,-1},dy[]= {1,-1,0,0}; struct nodes { int x,y; int color,cost;//-1表示没有变色,1红色,2黄色 } t; void bfs() { memset(vis,0x3f,sizeof vis); queue<nodes> q; q.push({1,1,-1,0}); vis[1][1]=0; while(!q.empty()) { t=q.front(); q.pop(); if(t.x==m&&t.y==m) {//出口 ans=min(ans,t.cost); continue; } if(t.cost>=ans) continue;//剪枝 for(int i=0; i<4; i++) { int xx=t.x+dx[i]; int yy=t.y+dy[i]; if(xx>=1&&xx<=m&&yy>=1&&yy<=m) {//在地图范围内 if(t.color==-1) { //原本格子有颜色 if(g[xx][yy]==g[t.x][t.y]&&vis[xx][yy]>t.cost) { //下一个格子颜色相同 vis[xx][yy]=t.cost; q.push({xx,yy,-1,t.cost}) ; } else if(g[xx][yy]!=0&&g[xx][yy]!=g[t.x][t.y]&&vis[xx][yy]>1+t.cost) {//下一个格子颜色不相同 vis[xx][yy]=t.cost+1; q.push({xx,yy,-1,t.cost+1}) ; } else if(g[xx][yy]==0&&vis[xx][yy]>=2+t.cost) { //填涂颜色 vis[xx][yy]=2+t.cost; q.push({xx,yy,g[t.x][t.y],t.cost+2}) ; } } else {//原本格子没有颜色,只能去有颜色的格子 if(g[xx][yy]!=0&&t.color==g[xx][yy]&&vis[xx][yy]>t.cost) { vis[xx][yy]=t.cost; q.push({xx,yy,-1,t.cost}) ; } else if(g[xx][yy]!=0&&t.color!=g[xx][yy]&&vis[xx][yy]>1+t.cost) { vis[xx][yy]=1+t.cost; q.push({xx,yy,-1,t.cost+1}) ; } } } } } return; } int main() { scanf("%d %d",&m,&n); for(int i=1; i<=n; i++) { scanf("%d %d %d",&x,&y,&c); g[x][y]=c+1;//1 红色,2 黄色, 0 无色 } bfs(); if(ans==N*N*2) { cout<<-1; } else cout<<ans; return 0; }