广度/宽度优先搜索(BFS)
2017-03-15 16:18
417 查看
引用一个大神的博客 ,
点击打开链接
上面
经典例题是一个迷宫问题 S表示起点,G表示终点,#表示墙壁, . 表示路,求最短距离
5 5
S####
..#..
#...#
#....
#G###
#include <iostream>
#include<queue>
using namespace std;
const int maxn=100+5;
const int INF=1000000000;
int sy,sx,gx,gy;
int d[maxn][maxn];
char maze[maxn][maxn];
int m,n;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
typedef pair<int,int> P;
int bfs()
{
queue<P> que;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
d[i][j]=INF;
que.push(P(sx,sy));
d[sx][sy]=0;
while(que.size())
{
P p=que.front();
que.pop();
if(p.first==gx&&p.second==gy)
break;
for(int i=0;i<4;i++)
{
int nx=p.first+dx[i],ny=p.second+dy[i];
if(0<=nx&&ny>=0&&nx<n&&ny<m&&maze[nx][ny]!='#'&&d[nx][ny]==INF)
{
que.push(P(nx,ny));
d[nx][ny]=d[p.first][p.second]+1;
}
}
}
return d[gx][gy];
}
void solve()
{
int res=bfs();
cout<<res<<endl;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>maze[i][j];
if(maze[i][j]=='S')
{
sx=i;
sy=j;
}
if(maze[i][j]=='G')
{
gx=i;gy=j;
}
}
solve();
return 0;
}
Poj上还有一道类似的但是比这个麻烦一点,要将走过的点输出的题目
定义一个二维数组:
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
代码如下
#include <iostream>
#include<queue>
#include<cstring>
#include<vector>
#include<cstdio>
#include<stack>
using namespace std;
const int maxn=100+5;
const int INF=0x3f3f3f3f;
int d[maxn][maxn];
int maze[maxn][maxn];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
struct P
{
int first,second;
P(int x=0,int y=0){first=x;second=y;}
};
P qre[10][10];
void bfs()
{
queue<P> que;
memset(d,0,sizeof(d));
d[0][0]=1;
que.push(P(0,0));
while(que.size())
{
P p=que.front();
que.pop();
for(int i=0;i<4;i++)
{
int nx=p.first+dx[i],ny=p.second+dy[i];
if(0<=nx&&ny>=0&&nx<5&&ny<5&&maze[nx][ny]==0&&d[nx][ny]==0)
{
que.push(P(nx,ny));
d[nx][ny]=1;
qre[nx][ny]=P(p.first,p.second);
}
if(p.first==4&&p.second==4)
return;
}
}
}
void solve()
{
bfs();
stack<P> s;
int cur=4,cul=4;
while(1)
{
s.push(P(cur,cul));
if(cur==0&&cul==0)
break;
int r=cur,c=cul;
cur=qre[r][c].first;
cul=qre[r][c].second;
4000
}
while(!s.empty())
{
P no=s.top();
s.pop();
printf("(%d, %d)\n",no.first,no.second);
}
}
int main()
{
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
cin>>maze[i][j];
}
solve();
return 0;
}
[cpp]
view plain
copy
/**
* 广度优先搜索
* @param Vs 起点
* @param Vd 终点
*/
bool BFS(Node& Vs, Node& Vd){
queue<Node> Q;
Node Vn, Vw;
int i;
//初始状态将起点放进队列Q
Q.push(Vs);
hash(Vw) = true;//设置节点已经访问过了!
while (!Q.empty()){//队列不为空,继续搜索!
//取出队列的头Vn
Vn = Q.front();
//从队列中移除
Q.pop();
while(Vw = Vn通过某规则能够到达的节点){
if (Vw == Vd){//找到终点了!
//把路径记录,这里没给出解法
return true;//返回
}
if (isValid(Vw) && !visit[Vw]){
//Vw是一个合法的节点并且为白色节点
Q.push(Vw);//加入队列Q
hash(Vw) = true;//设置节点颜色
}
}
}
return false;//无解
}
点击打开链接
上面
经典例题是一个迷宫问题 S表示起点,G表示终点,#表示墙壁, . 表示路,求最短距离
5 5
S####
..#..
#...#
#....
#G###
#include <iostream>
#include<queue>
using namespace std;
const int maxn=100+5;
const int INF=1000000000;
int sy,sx,gx,gy;
int d[maxn][maxn];
char maze[maxn][maxn];
int m,n;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
typedef pair<int,int> P;
int bfs()
{
queue<P> que;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
d[i][j]=INF;
que.push(P(sx,sy));
d[sx][sy]=0;
while(que.size())
{
P p=que.front();
que.pop();
if(p.first==gx&&p.second==gy)
break;
for(int i=0;i<4;i++)
{
int nx=p.first+dx[i],ny=p.second+dy[i];
if(0<=nx&&ny>=0&&nx<n&&ny<m&&maze[nx][ny]!='#'&&d[nx][ny]==INF)
{
que.push(P(nx,ny));
d[nx][ny]=d[p.first][p.second]+1;
}
}
}
return d[gx][gy];
}
void solve()
{
int res=bfs();
cout<<res<<endl;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>maze[i][j];
if(maze[i][j]=='S')
{
sx=i;
sy=j;
}
if(maze[i][j]=='G')
{
gx=i;gy=j;
}
}
solve();
return 0;
}
Poj上还有一道类似的但是比这个麻烦一点,要将走过的点输出的题目
定义一个二维数组:
int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, };
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
代码如下
#include <iostream>
#include<queue>
#include<cstring>
#include<vector>
#include<cstdio>
#include<stack>
using namespace std;
const int maxn=100+5;
const int INF=0x3f3f3f3f;
int d[maxn][maxn];
int maze[maxn][maxn];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
struct P
{
int first,second;
P(int x=0,int y=0){first=x;second=y;}
};
P qre[10][10];
void bfs()
{
queue<P> que;
memset(d,0,sizeof(d));
d[0][0]=1;
que.push(P(0,0));
while(que.size())
{
P p=que.front();
que.pop();
for(int i=0;i<4;i++)
{
int nx=p.first+dx[i],ny=p.second+dy[i];
if(0<=nx&&ny>=0&&nx<5&&ny<5&&maze[nx][ny]==0&&d[nx][ny]==0)
{
que.push(P(nx,ny));
d[nx][ny]=1;
qre[nx][ny]=P(p.first,p.second);
}
if(p.first==4&&p.second==4)
return;
}
}
}
void solve()
{
bfs();
stack<P> s;
int cur=4,cul=4;
while(1)
{
s.push(P(cur,cul));
if(cur==0&&cul==0)
break;
int r=cur,c=cul;
cur=qre[r][c].first;
cul=qre[r][c].second;
4000
}
while(!s.empty())
{
P no=s.top();
s.pop();
printf("(%d, %d)\n",no.first,no.second);
}
}
int main()
{
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
cin>>maze[i][j];
}
solve();
return 0;
}
核心代码
为了方便适用于大多数的题解,抽取核心代码如下:[cpp]
view plain
copy
/**
* 广度优先搜索
* @param Vs 起点
* @param Vd 终点
*/
bool BFS(Node& Vs, Node& Vd){
queue<Node> Q;
Node Vn, Vw;
int i;
//初始状态将起点放进队列Q
Q.push(Vs);
hash(Vw) = true;//设置节点已经访问过了!
while (!Q.empty()){//队列不为空,继续搜索!
//取出队列的头Vn
Vn = Q.front();
//从队列中移除
Q.pop();
while(Vw = Vn通过某规则能够到达的节点){
if (Vw == Vd){//找到终点了!
//把路径记录,这里没给出解法
return true;//返回
}
if (isValid(Vw) && !visit[Vw]){
//Vw是一个合法的节点并且为白色节点
Q.push(Vw);//加入队列Q
hash(Vw) = true;//设置节点颜色
}
}
}
return false;//无解
}
相关文章推荐
- 广度/宽度优先搜索(BFS)(给了部分题目)
- 广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)详解
- 【算法入门】广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)
- BFS-迷宫问题-用宽度(广度)优先搜索解决最优路径问题
- 【算法入门】广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)详解
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 广度/宽度优先搜索(BFS)