• E - Fire! (双向bfs)


    UVA-11624-Fire!

     

    题意:在n*m的网格内,有一个人和n堆火,人可以往上下左右四个方向走,同时所有的火也会想四周蔓延,问你人可不可以在火包围他之前逃离这个n*m的范围。

    思路:问人可不可以逃离这个范围,就是看人能不能走到最外面的一圈的格子。但是人在走的时候火也会走,那么我们就要进行人 和火的同时的bfs,人和火同时bfs同时更新状态,首先对于人,人先往四周bfs,但是问题来了,我们怎么判断什么时候这一轮人的bfs应该停止去进行火的bfs——————我们可以在每次bfs之前去记录队列中包含的元素,只要对队列的元素进行 bfs就可以停止了,之后对火的bfs就可以了。但是有个问题需要注意一下,就是当人的bfs之后,火可能会把人能走的位置直接封住,但是人的可能的情况已经进入队列了,我们再删除也不好处理,那么我们可以逆向思维先bfs火的范围的,因为火如果先走的话那么人直接走能走的点就可以了

    那么最后的整体的框架就是:

    先bfs火能走的范围

    然后bfs人能走的范围

    每次bfs的次数是bfs之前队列的元素的个数

    注意最后到达最外圈的结果应该要+1才能出去

    最后我bfs的标记写错了,我的每次标记时是在出队的时候再标记

    但是正确的标记应该是在入队的时候就去标记,因为如果是在出队时才标记,那么可能会标记很多重复的元素导致t(比如我入队了{1,2,3}三个元素,然后到1这个元素的时候也可能会入队{2,3}这两个元素,而先标记1 2 3三个元素在之后就不会出现重复入队的情况),当时就卡了这个点qwq!!!

    代码

    1. /**
    2. *  ┏┓   ┏┓+ +
    3. * ┏┛┻━━━┛┻┓ + +
    4. * ┃       ┃
    5. * ┃   ━   ┃ ++ + + +
    6. * ████━████+
    7. * ◥██◤ ◥██◤ +
    8. * ┃   ┻   ┃
    9. * ┃       ┃ + +
    10. * ┗━┓   ┏━┛
    11. *   ┃   ┃ + + + +Code is far away from  
    12. *   ┃   ┃ + bug with the animal protecting
    13. *   ┃    ┗━━━┓ 神兽保佑,代码无bug 
    14. *   ┃       ┣┓
    15. *   ┃        ┏┛
    16. *  ┗┓┓┏━┳┓┏┛ + + + +
    17. *    ┃┫┫ ┃┫┫
    18. *    ┗┻┛ ┗┻┛+ + + +
    19. */
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #define sc_int(x) scanf("%d", &x)
    30. #define sc_ll(x) scanf("%lld", &x)
    31. #define pr_ll(x) printf("%lld", x)
    32. #define pr_ll_n(x) printf("%lld\n", x)
    33. #define pr_int_n(x) printf("%d\n", x)
    34. #define ll long long
    35. using namespace std;
    36. const int N = 1000000 + 100;
    37. int n, m, h;
    38. ll s[N];
    39. char Map[1010][1010];
    40. struct lk
    41. {
    42. int x;
    43. int y;
    44. int cnt;
    45. };
    46. queue q, p;
    47. int dirx[5] = {0, 1, 0, -1, 0};
    48. int diry[5] = {0, 0, -1, 0, 1};
    49. bool st[1010][1010];
    50. bool stf[1010][1010];
    51. void bfs(int a, int b)
    52. {
    53. q.push({a, b, 0});
    54. st[a][b] = 1;
    55. int sum=0;
    56. while (q.size() )
    57. {
    58. while (p.size())
    59. {
    60. lk kk = p.front();
    61. if (kk.cnt > sum)
    62. break;
    63. p.pop();
    64. // cout<
    65. for (int i = 1; i <= 4; i++)
    66. {
    67. int xx = kk.x + dirx[i], yy = kk.y + diry[i];
    68. if (xx < 1 || xx > n || yy < 1 || yy > m)
    69. continue;
    70. if ( Map[xx][yy] != '.')
    71. continue;
    72. // cout<
    73. Map[xx][yy]='F';
    74. p.push({xx, yy, kk.cnt + 1});
    75. }
    76. }
    77. while (q.size())
    78. {
    79. lk k = q.front();
    80. if(k.cnt>sum)break;
    81. q.pop();
    82. // cout<
    83. if (k.x == 1 || k.x == n || k.y == 1 || k.y == m)
    84. {
    85. cout << k.cnt+1 << endl;
    86. return;
    87. }
    88. for (int i = 1; i <= 4; i++)
    89. {
    90. int xx = k.x + dirx[i], yy = k.y + diry[i];
    91. if (xx < 1 || xx > n || yy < 1 || yy > m)
    92. continue;
    93. if (st[xx][yy] || Map[xx][yy] == '#'||Map[xx][yy]=='F')
    94. continue;
    95. st[xx][yy] = 1;
    96. q.push({xx, yy, k.cnt + 1});
    97. }
    98. }
    99. sum++;
    100. }
    101. cout << "IMPOSSIBLE\n";
    102. return;
    103. }
    104. int main()
    105. {
    106. int t;
    107. sc_int(t);
    108. while (t--)
    109. {
    110. memset(st,0,sizeof st);
    111. while(q.size())q.pop();
    112. while(p.size())p.pop();
    113. int x, y;
    114. cin >> n >> m;
    115. for (int i = 1; i <= n; i++)
    116. cin >> Map[i] + 1;
    117. for (int i = 1; i <= n; i++)
    118. {
    119. for (int j = 1; j <= m; j++)
    120. {
    121. if (Map[i][j] == 'F')
    122. {
    123. p.push({i, j, 0});
    124. stf[i][j] = 1;
    125. }
    126. if (Map[i][j] == 'J')
    127. {
    128. x = i;
    129. y = j;
    130. }
    131. }
    132. }
    133. bfs(x, y);
    134. }
    135. return 0;
    136. }

     

  • 相关阅读:
    基于HFSS的T型功分波导设计
    Oracle中instr,rtrim,XMLPARSE,XMLAGG,GETCLOBVAL函数的使用
    UDP和TCP的区别
    自动驾驶中的人机互相接管问题讨论
    Spring IOC和AOP
    【ES】笔记-Class类剖析
    C语言求矩阵的逆(初等行变换法)
    计算机视觉基础知识(十六)--图像识别
    全局大喇叭--广播机制
    RxJS 实战: 基于 BehaviorSubject 实现状态管理 & 结合 React
  • 原文地址:https://blog.csdn.net/jikelk/article/details/127989650