Problem p00481 (C++) — buggy submission, verdict: Memory Limit Exceeded

#if 0
#cflags(-std = c++ 14 - Wall)
#endif
#include <iostream>
template <typename T> T input(std::istream &os = std::cin) {
  T t;
  os >> t;
  return t;
}

#include <numeric>
#include <queue>
#include <string>
#include <vector>

struct pos {
  int x, y;
  template <typename T> auto &&operator[](T &&t) const {
    return std::forward<T>(t)[y][x];
  }
};
template <typename F> struct itr {
  int r;
  std::pair<pos, int> t;
  F shortest;
  bool flag;
  itr &operator++() {
    ++r;
    flag = true;
    return *this;
  }
  int &operator*() {
    if (flag)
      t = shortest(r, t.first.x, t.first.y), flag = false;
    return t.second;
  }
  bool operator==(const itr &other) const { return r == other.r; }
  bool operator!=(const itr &other) const { return !(*this == other); }
};
template <typename F> itr<F> make_itr(const pos &p, F &&f) {
  return ++itr<F>{0, {p, 0}, f};
}
template <typename F> itr<F> make_itr(int r, F &&f) { return itr<F>{r, {}, f}; }

int main() {
  const auto H = input<int>();
  const auto W = input<int>();
  const auto N = input<int>();
  const std::vector<std::string> data = [H] {
    std::vector<std::string> data;
    data.reserve(H);
    for (int i = 0; i < H; ++i)
      data.emplace_back(input<std::string>());
    return data;
  }();
  const pos po = [&] {
    pos po;
    for (int j = 0; j < H; ++j)
      for (int i = 0; i < W; ++i)
        if (data[j][i] == 'S')
          po = {i, j};
    return po;
  }();
  auto shortest = [&](int rank, int i, int j) {
    std::vector<std::vector<char>> flags(H, std::vector<char>(W));
    std::queue<std::pair<pos, int>> q;
    q.push({{i, j}, 0});
    flags[j][i] = true;
    while (true) {
      const auto &d = q.front();
      const auto &p = d.first;
      if (p[data] == rank + '0')
        return q.front();
      p[flags] = true;
      auto add = [&](const pos &po) {
        if (!po[flags])
          if (po[data] != 'X')
            q.push({po, d.second + 1}), po[flags] = true;
          else
            po[flags] = true;
      };
      for (int a = -1; a <= 1; a += 2)
        if (0 <= p.x + a && p.x + a < W)
          add(pos{p.x + a, p.y});
      for (int b = -1; b <= 1; b += 2)
        if (0 <= p.y + b && p.y + b < H)
          add(pos{p.x, p.y + b});
      q.pop();
    }
    return q.front();
  };
  std::cout << std::accumulate(make_itr(po, shortest),
                               make_itr(N + 1, shortest), 0)
            << std::endl;
}

Error: MLE

Fixed submission:

#if 0
#cflags(-std = c++ 14 - Wall)
#endif
#include <iostream>
template <typename T> T input(std::istream &os = std::cin) {
  T t;
  os >> t;
  return t;
}

#include <numeric>
#include <queue>
#include <string>
#include <vector>

struct pos {
  int x, y;
  template <typename T> auto operator[](T &&t) const {
    return std::forward<T>(t)[y][x];
  }
};
template <typename F> struct itr {
  int r;
  std::pair<pos, int> t;
  F shortest;
  itr &operator++() {
    ++r;
    return *this;
  }
  int &operator*() {
    t = shortest(r, t.first.x, t.first.y);
    return t.second;
  }
  bool operator==(const itr &other) const { return r == other.r; }
  bool operator!=(const itr &other) const { return !(*this == other); }
};
template <typename F> itr<F> make_itr(const pos &p, F &&f) {
  return ++itr<F>{0, {p, 0}, f};
}
template <typename F> itr<F> make_itr(int r, F &&f) { return itr<F>{r, {}, f}; }

int main() {
  const auto H = input<int>();
  const auto W = input<int>();
  const auto N = input<int>();
  const std::vector<std::string> data = [H] {
    std::vector<std::string> data;
    data.reserve(H);
    for (int i = 0; i < H; ++i)
      data.emplace_back(input<std::string>());
    return data;
  }();
  const std::vector<pos> poss = [&] {
    std::vector<pos> poss(10);
    for (int j = 0; j < H; ++j)
      for (int i = 0; i < W; ++i)
        if (data[j][i] == 'S')
          poss[0] = {i, j};
        else if ('1' <= data[j][i] && data[j][i] <= '9')
          poss[data[j][i] - '0'] = {j, i};
    return poss;
  }();
  auto shortest = [&](int rank, int i, int j) {
    std::vector<std::vector<bool>> flags(H, std::vector<bool>(W));
    std::queue<std::pair<pos, int>> q;
    q.push({{i, j}, 0});
    while (true) {
      const auto &d = q.front();
      const auto &p = d.first;
      if (p[data] == rank + '0')
        return q.front();
      p[flags] = true;
      auto add = [&](const pos &po) {
        if (!po[flags])
          if (po[data] != 'X')
            q.push({po, d.second + 1});
          else
            p[flags] = true;
      };
      for (int a = -1; a <= 1; a += 2)
        if (0 <= p.x + a && p.x + a < W)
          add(pos{p.x + a, p.y});
      for (int b = -1; b <= 1; b += 2)
        if (0 <= p.y + b && p.y + b < H)
          add(pos{p.x, p.y + b});
      p[flags] = true;
      q.pop();
    }
    return q.front();
  };
  std::cout << std::accumulate(make_itr(poss[0], shortest),
                               make_itr(N + 1, shortest), 0)
            << std::endl;
}