[ACM算法日记]BFS宽搜

预备知识

  1. 队列(STL容器的使用)

2. 树的层次遍历

算法思想: 维护一个队列,用于存放节点的信息。当访问到一个节点的时候,先访问该节点,然后将该节点的左右儿子分别入队列。
伪代码:

ccbl(int root)
	queue<int > q;
	q.push(root);
	while(队列非空){
		获得队首元素
		将队首元素出队
		操作当前节点值
		如果左儿子非空,将左儿子加入队列
		如果右儿子非空,将右儿子加入队列····            吧,·,iiiiiiii
	}
  1. 的遍历

基本思想

状态转移——从一个大规模状态转移到小规模状态

通过维护一个队列来完成状态转移, 在各个状态之间变化直到搜索到目标状态
任何一个问题,只要能把状态表示出来,并且描述出状态转移的规则,就能用搜索做,本质就是暴力枚举

优化

  1. 做标记,重复的不处理
  2. 其他剪枝

代码实现

BFS的代码实现非常模式化,直接套模板即可,但是要注意对数据处理时的一些细节。

#include <bits/stdc++.h>
using namespace std;
typedef struct pos pos;
int vis[201];
int k[207];
int n;
struct pos {
    int level, step;
};
void bfs(int start, int end);
int main (void) {
    int start, end;
    while(cin >> n, n)
    {
        cin >> start >> end;
        for (int i = 1; i <= n; ++i)
            cin >> k[i];
        bfs(start, end);
        memset(vis, 0, sizeof(vis));
    }
    return 0;
}
void bfs(int start, int end) {
    queue<pos> qu;
    pos cur, nex;
    cur.level = start, cur.step = 0;
    qu.push(cur);
    vis[start] = 1;
    while(!qu.empty()) {
        cur = qu.front();
        qu.pop();
        if (cur.level == end) {
            printf("%d\n", cur.step);
            return;
        }
        nex.step = cur.step + 1;
        nex.level = cur.level + k[cur.level];
        if (vis[nex.level] != 1 && nex.level <= n) {
            vis[nex.level] = 1;
            qu.push(nex);
        }
        nex.level = cur.level - k[cur.level];
        if (vis[nex.level] != 1 && nex.level >= 1) {
            vis[nex.level] = 1;
            qu.push(nex);
        }
    }
    printf("-1\n");
    return;
}

注意!

  1. 如果吧队列设置为全局变量,记得每次组数据要清空队列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值