博客 > 数据结构&算法 > 题目&比赛
# HDU-2612 双BFS ## [HDU-2612](http://acm.hdu.edu.cn/showproblem.php?pid=2612) ## 分析 老暴力了, 就是**从M和Y分别出发BFS顺便记录步数, 然后遍历步数矩阵, 找相加时的最小值**. 需要注意的地方是记录步数时必须将默认步数设为无穷值(INF), 并且INF必须在**机器最大值的1/2**(比如0x7fffffff的1/2, 如果使用有符号int的话)和**最大可能步数**之间, 而**不能为0**. 这是因为题目并不保证所有KFC(@)都能走到, 这样最后会产生INF+INF, 不管是初始值为0还是超过了整型最大值的1/2, 最终结果都会出现非预期的错误. 在这里坑了很久. > **0x3f3f3f3f**是INF的惯用取值, 正好满足上述特性. 详情参见[这篇博客](https://blog.csdn.net/mlm5678/article/details/82729974?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase) ## 心得 原来还想过同步双向BFS(把第一次访问到另一个人来过的KFC时的情况作为最优解), 后来发现想错了. 目前看来只能两遍完整BFS. 比如出现这种情况, 同步双向BFS就会出问题: | # | Y | # | ... | |:---:|:---:|:---:|:---:| | | | | ... | | | # | 3 | ... | | | 5 | ! | ... | | ... | ... | ... | ... | 3 5代表Y到两个KFC的距离, !代表假设M遍历到的位置. 这时如果M优先走左侧, 就WA了. ## 代码 原型来自HDU讨论区 ```cpp // -------------- GLOBAL ---------------- char map1[250][250]; // YM.#@! int booky[250][250], bookm[250][250]; int n, m; int y1, y2, m1, m2; // -------------- FUNC ---------------- void bfs(int x, int y, int book[250][250]) { queue<pair<int, int>> que; que.push({x, y}); book[x][y] = 0; while (!que.empty()) { auto p = que.front(); F0(i, 4) { int tx = p.fs + dir[i][0]; int ty = p.se + dir[i][1]; if (tx < 0 || ty < 0 || tx >= n || ty >= m) continue; if (book[tx][ty] != INF) continue; if (map1[tx][ty] == '.' || map1[tx][ty] == '@') { que.push({tx, ty}); book[tx][ty] = book[p.fs][p.se] + 1; } } que.pop(); } } // -------------- MAIN ---------------- int main() { //ios_base::sync_with_stdio(false); while (~scanf("%d%d", &n, &m)) { memset(booky, 0x3F, sizeof(booky)); memset(bookm, 0x3F, sizeof(bookm)); fill0(map1); F0(i, n) { getchar(); F0(j, m) { scanf("%c", &(map1[i][j])); switch (map1[i][j]) { case 'Y': y1 = i, y2 = j; break; case 'M': m1 = i, m2 = j; break; } } } bfs(y1, y2, booky); bfs(m1, m2, bookm); int res = INF; F0(i, n) { F0(j, m) { if (map1[i][j] == '@') { res = min(res, booky[i][j] + bookm[i][j]); } } } printf("%d\n", res * 11); } return 0; } ```