您的位置:首页 > 其它

广度/宽度优先搜索(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上还有一道类似的但是比这个麻烦一点,要将走过的点输出的题目

定义一个二维数组:

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;//无解  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: