第一次广搜!HDU1548--A Strange Lift
一上来看见题目就用了深搜(因为只会深搜)果断内存超限(据说时间也会超限)无奈只好开始用广搜
其实广搜的思路和深搜有很多类似的地方 不过实现的过程中用到了队列 因此有点难以理解(好吧我个人认为)
这题是最基本的广搜了 只是一个二叉树
所以先画个二叉树出来看一下广搜的顺序
每一个节点下一层的节点入队之后就把这个节点出队
对每一个节点 bfs的顺序是这样的
1.将这个节点的左节点入队(要判断左节点是否已经入队以及是否合适)
2.将这个节点的右节点入队(同样也要盘算右节点是否已经入队以及是否满足条件)
3.判断该节点是否满足条件 如果满足 就return(这时候一定是最短路径因为是一层一层分析的)
4.将该节点出队
当所有的节点都出队时说明已经把所有可能的路径都遍历了一遍(有关结束时机的判断还是有点疑问:这个题目当中是当没有合适的子节点时队列就空了 那么有没有可能出现超限或者死循环的情况呢?)
下面贴代码(模仿的)
# include<iostream> # include<queue> using namespace std; const int MAX_NUM = 205; struct node { int floor; int step; }; queue<node>note; int vis[MAX_NUM]; int k[MAX_NUM]; int A,B, N; struct node temp,m; int bfs() { struct node start; start.floor = A; start.step = 0; note.push(start); vis[start.floor] = 1; while (!note.empty())//结束的时机要想清楚 { temp = note.front();//临时变量的引入,使程序逻辑性更清晰 int up = temp.floor + k[temp.floor]; if (up<=N&&vis[up]==0) { vis[up] = 1; m.floor = up; m.step = temp.step + 1; note.push(m); } int down = temp.floor - k[temp.floor]; if (down > 0 && vis[down] == 0) { vis[down] = 1; m.floor = down; m.step = temp.step + 1; note.push(m); } if (temp.floor == B) { return temp.step;//不用考虑比较最小路径 这是和深搜不同的一点 } note.pop(); } return -1; } int main() { while (1) { cin >> N; if (N == 0) break; cin >> A >> B; for (int i = 1; i <= N; i++) { cin >> k[i]; } memset(vis, 0, sizeof(vis)); while (!note.empty()) { note.pop(); } /*将队列和访问标记初始化*/ cout << bfs() << endl; } return 0; }
算法的路还有很长 搜索只是刚刚入门啊!