预备知识
- 队列(STL容器的使用)
2. 树的层次遍历
算法思想: 维护一个队列,用于存放节点的信息。当访问到一个节点的时候,先访问该节点,然后将该节点的左右儿子分别入队列。
伪代码:
ccbl(int root)
queue<int > q;
q.push(root);
while(队列非空){
获得队首元素
将队首元素出队
操作当前节点值
如果左儿子非空,将左儿子加入队列
如果右儿子非空,将右儿子加入队列···· 吧,·,iiiiiiii
}
- 图的遍历
基本思想
状态转移——从一个大规模状态转移到小规模状态
通过维护一个队列来完成状态转移, 在各个状态之间变化直到搜索到目标状态
任何一个问题,只要能把状态表示出来,并且描述出状态转移的规则,就能用搜索做,本质就是暴力枚举
优化
- 做标记,重复的不处理
- 其他剪枝
代码实现
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;
}
注意!
- 如果吧队列设置为全局变量,记得每次组数据要清空队列