【HDOJ 2019寒假训练】BFS(宽搜)总结篇

【BFS算法工作机制】
由一点引起的、对周围的数据进行盲目搜寻(即无权值路径),根据这一点bfs更多用于坐标化的迷宫,或者不需要考虑有关路径权值大小的图形等的抽象搜索问题。
可以将bfs的过程想象成水波的涟漪
即若每一个搜索中心即水波的中心,则从该搜索中心出发经由的搜索点则是同一涟漪环上的点。然后涟漪上的点又充当新的搜索中心,以此类推。

(每一点的数字表示搜到该点的最短单位时间)

【实现机制】
bfs的实现通常通过队列queue实现。先向queue中加入初始的搜索起点,然后通过设立具有串联性质的cur和next元素(当然对于同一cur,next1与next2之间属于并联关系),不断弹出、加入,直至搜索到所需目标或者元素全部弹光为止。若中途搜到所需目标则搜索成功,反之则失败。

其中,由于在实际应用中bfs搜索的方向非常多,为了防止memory limit excessive,需要使用另外的剪枝数组防止发生不必要的回溯来避免其内存的占用

【变量设计】

  1. 队列包含元素的设计:绝大部分使用结构体作为每一步的载体。由于队列中的每一个元素需要同时包含当前一步中①需要实时更新并且对结果有影响的变量②用于判断是否搜到所需目标的变量③搜到目标时的返回值(即所需值)④一些每一步都需要进行操作的函数(不是必须的)
  2. 剪枝数组的设计:核心问题是哪些变量能够共同唯一地定义某一步(即当这些变量相同时才能够准确无误地认为这一步已经走过、从而不需要将其加入que中),而这些变量的总数决定了数组的维度,每一维用于表示某一变量的值。

【做题反思】
1.仔细读题,注意多组测试数据的时候,若同一题用的是同一队列,则要先清空前一组中队列里剩下的元素。
2.注意判断每一个next是否要放入que中时,判断的层次性,并且注意讨论的全面性。
3.在简单的地图中判断某一点是否搜索过时,搜到该点最短的时间=>该点是否被搜过;另外,由于bfs严格的串联关系,串联关系上的元素搜索所需时间严格递增,并联关系上的元素搜索所需时间严格相等,即某一点的搜索最短时间一旦被确定下来就不会再改变。这两点在具体的程序设计中会体现出来,在设计变量、程序时也可以根据此来安排。

【常用变量、常量】
int direct[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
typename graph[x][y]; //表示地图
bool hush[x][y]; //剪枝数组
struct node{ //存储每一步的信息
int x,y;
int time;
bool check();

}

【常用伪代码】

bool bfs(){             //根据问题所需可以改变函数类型
    //根据输入定义first
    queue<node>que;
    que.push(first);
    while(!que.empty()){
        struct node cur=que.front();
        que.pop();
        if(judge(cur))
            return true;            //根据问题所需可以返回当前点的各种信息
        for(int i=0;i<4;i++){       //对不同方向的遍历
            struct node next;
            next.x=cur.x+direct[i][0];next.y=cur.y+direct[i][1];next.question=cur.question+1;
            if(cur.check()&&!hush[][]...[]){     //广义上对于该点是否应该被加入que中的判断
                que.push(next);
                hush[][]...[]=true;
            }
        }
    }
    return false;
}

【结语】
是寒假刷完的第一个专题…刷了整整一周但是收获的确还是很大的,比如之前写的双bfs推箱子也可以试着用bfs+dfs来写写看、等等。
真正比赛的时候搜索的应用变化多端而且有些还是抽象的运用,所以要不断提高自己对于复杂搜索问题的敏感性、培养搜索建模的能力。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值