bfs 新思索

最近继续做bfs tag的题,有了一些新的思索。

  1. 每次bfs的时候,我们总把新元素放到队列后面。但其实我们常常遇到的这种情况 是另外一种情况的简化版,在那一种hard模式的版本中,队列是用的双端队列。
    1. 若新元素与当前相比 并没有实际的进展,则新元素被放到队首,反之放到队尾。这时,整个双端队列分为两级、分为两部分,前面的是同一级的,后面的下一级的。具体题型见lc1263 推箱子

2. 在bfs时,我们使用vis来标记某个元素是否曾经访问过。在一个图中,若这种遍历边 并 判断是否曾经访问过的行为就有很多时间开销了,那我们就可以采用list来记录某个节点的边们,并将访问过的边去掉,具体题目见lc1345 跳跃游戏IV。list相关代码如下:

        auto it = list.begin();
        while (it != list.end()) {
          int next_x = (*it);
          if (!vis[next_x]) {
            vis[next_x] = true;
            q.push(next_x);
            if (next_x == desi) {
              return step;
            }
            list.erase(it++);
          } else {
            it++;
          }
        }