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

#include <iostream>
#include <queue>
#include <set>

using namespace std;
typedef pair<int, int> pii;
typedef pair<int, set<pii>> pis;
typedef pair<pii, pis> pp;
int dy[4] = {-1, 0, 1, 0};
int dx[4] = {0, 1, 0, -1};
int g[21][21];
int w, h;
int sx, sy, gx, gy;
queue<pp> que;

bool f(int ny, int nx) {
  if (ny >= 0 && ny < h && nx >= 0 && nx < w)
    return true;
  else
    return false;
}

int bfs(int c) {
  while (!que.empty()) {
    pp p = que.front();
    que.pop();
    int ty = p.first.first, tx = p.first.second, c = p.second.first;
    set<pii> se = p.second.second;
    if (c == 10)
      return -1;

    for (int i = 0; i < 4; i++) {
      int ny = ty, nx = tx;
      if (g[ny + dy[i]][nx + dx[i]] == 1 &&
          !se.count(make_pair(ny + dy[i], nx + dx[i])))
        continue;
      while (f(ny + dy[i], nx + dx[i]) &&
             (g[ny + dy[i]][nx + dx[i]] != 1 ||
              se.count(make_pair(ny + dy[i], nx + dx[i])))) {
        ny += dy[i], nx += dx[i];
        if (ny == gy && nx == gx)
          return c + 1;
      }
      if (ny + dy[i] < 0 || ny + dy[i] >= h || nx + dx[i] < 0 ||
          nx + dx[i] >= w)
        continue;
      set<pii> s = se;
      s.insert(make_pair(ny + dy[i], nx + dx[i]));
      que.push(make_pair(make_pair(ny, nx), make_pair(c + 1, s)));
    }
  }
  return -1;
}

int main(void) {
  while (cin >> w >> h && w) {
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> g[i][j];
        if (g[i][j] == 2)
          sy = i, sx = j;
        if (g[i][j] == 3)
          gy = i, gx = j;
      }
    }
    queue<pp> empty;
    que = empty;
    set<pii> se;
    que.push(make_pair(make_pair(sy, sx), make_pair(0, se)));
    cout << bfs(0) << endl;
  }
}

Error: MLE

Fixed submission:

#include <iostream>
#include <queue>
#include <set>

using namespace std;
typedef pair<int, int> pii;
typedef pair<int, set<pii>> pis;
typedef pair<pii, pis> pp;
int dy[4] = {-1, 0, 1, 0};
int dx[4] = {0, 1, 0, -1};
int g[21][21];
int w, h;
int sx, sy, gx, gy;
queue<pp> que;

bool f(int ny, int nx) {
  if (ny >= 0 && ny < h && nx >= 0 && nx < w)
    return true;
  else
    return false;
}

int bfs(int c) {
  if (c == 10)
    return -1;
  queue<pp> next;
  while (!que.empty()) {
    pp p = que.front();
    que.pop();
    int ty = p.first.first, tx = p.first.second, b = p.second.first;
    set<pii> se = p.second.second;
    for (int i = 0; i < 4; i++) {
      int ny = ty, nx = tx;
      if (g[ny + dy[i]][nx + dx[i]] == 1 &&
          !se.count(make_pair(ny + dy[i], nx + dx[i])))
        continue;
      while (f(ny + dy[i], nx + dx[i]) &&
             (g[ny + dy[i]][nx + dx[i]] != 1 ||
              se.count(make_pair(ny + dy[i], nx + dx[i])))) {
        ny += dy[i], nx += dx[i];
        if (ny == gy && nx == gx)
          return c + 1;
      }
      if (ny + dy[i] < 0 || ny + dy[i] >= h || nx + dx[i] < 0 ||
          nx + dx[i] >= w)
        continue;
      set<pii> s = se;
      s.insert(make_pair(ny + dy[i], nx + dx[i]));
      next.push(make_pair(make_pair(ny, nx), make_pair(i, s)));
    }
  }
  que = next;
  return bfs(c + 1);
}

int main(void) {
  while (cin >> w >> h && w) {
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> g[i][j];
        if (g[i][j] == 2)
          sy = i, sx = j;
        if (g[i][j] == 3)
          gy = i, gx = j;
      }
    }
    queue<pp> empty;
    que = empty;
    set<pii> se;
    que.push(make_pair(make_pair(sy, sx), make_pair(-1, se)));
    cout << bfs(0) << endl;
  }
}