广度优先搜索——BFS遍历

 广度优先搜索(Breadth First Search , BFS)是一个分层搜索的过程,没有回退过程,是非递归的

为避免重复访问,需要一个状态数组visited[n]来存储各顶点的访问状态。为实现逐层访问,bfs算法在实现时需要一个队列,以记忆正在访问的这一层和上一层的顶点,以便于向下一层访问。

例题(1):营救(rescue)

输入描述:"."  :道路  "r" :Angle的朋友 "#" :墙壁  "x" :警卫

分析:本题要求从r位置出发到达Angel所在的位置且所需时间最少,适合bfs求解。但在本题中,步数最少的解不一定是最优解。

为求出最优解,采用如下的思路进行bfs搜索。

(1)将Angel的朋友到达某个方格的状态用一个结构体point表示,该结构体包含了Angel的朋友到达该方格时所走过的步数及所花费的时间;在bfs搜索中,队列中的结点是point型数据.

(2)定义一个二维数组mintime,mintime[i][j]表示Angel的朋友走到(i,j)位置所需的最少时间;在bfs搜索过程中,从当前位置走到相邻的位置(x,y)时,只有当该种走法比走到(x,y)所需的时间更少时,才会把当前走到(x,y)位置的状态入队列,否则是不会入队列的。

(3)不能一判断出到达目标位置就退出bfs过程,否则求出的最小时间仅仅是从r到达a最小步数的若干方案中的最小时间,不一定是最优解,一定要等到队列为空,才能得出结论。

另外在题目中未使用visited[n]数组,因为只有当下一个位置比上一个所需的时间少才能入队列,所以到达(x,y)的最少时间肯定是有下界的。

#include
#include
#include
#include
#define maxint 0x3f3f3f3f
#define MAXN 200
using namespace std;
struct point
{
    int x,y;
    int step;
    int time;
};
queueQ;
int n,m;
char map[MAXN][MAXN];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int mintime[MAXN][MAXN];
int ax,ay;///Angel所在的位置
int bfs(point s);
int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(mintime,maxint,sizeof(mintime));
        memset(map,0,sizeof(map));
        for(i=0;i=0&&y>=0&&x<=n-1&&y<=m-1&&map[x][y]!='#')
            {
                point t;
                t.x=x;
                t.y=y;
                t.step=hd.step+1;
                t.time=hd.time+1;
                if(map[x][y]=='x') t.time++;///杀死警卫的时间
              ///如果比最少时间少,则将t入队列
                if(t.time
广度优先搜索的伪代码

(1)若用邻接表存储图

dfs(顶点i)
{
    visited[i]=1;
    将顶点i入队列;
    while(队列不为空)
    {
        取出队列头的顶点,设为k;
        p=顶点k的边链表表头指针;
        while(p不为空)
        {
            ///设指针p指向的边结点所表示的边的另一个顶点为j;
            if(顶点j未访问过)
            {
                将顶点j标记为访问;
                将顶点j入队列;
            }
            p=p->next;
        }
    }
}

(2)用邻接矩阵存储图

dfs(顶点i)
{
    visited[i]=1;
    将顶点i入队列;
    while(队列不为空)
    {
        取出队列头的顶点,设为k;
        for(j=0;j



你可能感兴趣的:(图论)