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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

#define MAX_H 7
#define MAX_W 7

int w, h;
int gy, gx;
int F[MAX_H][MAX_W];

struct P {
  int wx, wy;
  int cx, cy;
  int t;
};

const int dy[] = {0, 1, 0, -1};
const int dx[] = {1, 0, -1, 0};
bool used[MAX_H][MAX_W][MAX_H][MAX_W]; // 荷物の座標, ミスターの座標

bool v[MAX_H][MAX_W];
bool can_move_to(int fy, int fx, int ty, int tx) {
  if (ty == fy && tx == fx)
    return true;
  if (F[ty][tx] == 1)
    return false;
  if (F[fy][fx] == 1)
    return false;
  for (int i = 0; i < 4; i++) {
    int ny = fy + dy[i];
    int nx = fx + dx[i];
    if (0 <= ny && ny < h && 0 <= nx && nx < w && !v[ny][nx]) {
      v[fy][fx] = true;
      if (can_move_to(ny, nx, ty, tx))
        return true;
    }
  }
  return false;
}

int bfs(P cur) {
  queue<P> q;
  q.push(cur);
  memset(used, 0, sizeof(used));
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    if (p.cy == gy && p.cx == gx)
      return p.t;
    for (int i = 0; i < 4; i++) {
      int ny = p.cy + dy[i];
      int nx = p.cx + dx[i];
      int py = p.cy - dy[i];
      int px = p.cx - dx[i];
      P next;
      next.wy = p.cy;
      next.wx = p.cx;
      next.cy = ny;
      next.cx = nx;
      next.t = p.t + 1;
      if (0 <= ny && ny < h && 0 <= nx && nx < w && 0 <= py && py < h &&
          0 <= px && px < w && F[ny][nx] != 1 &&
          !used[next.cy][next.cx][next.wy][next.wx]) {
        memset(v, 0, sizeof(v));
        F[p.cy][p.cx] = 1;
        if (can_move_to(p.wy, p.wx, py, px)) {
          used[next.cy][next.cx][next.wy][next.wx] = true;
          q.push(next);
        }
        F[p.cy][p.cx] = 0;
      }
    }
  }
  return -1;
}

int main() {
  while (cin >> w >> h, w || h) {
    P cur;
    cur.t = 0;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        cin >> F[i][j];
        if (F[i][j] == 4) {
          cur.wy = i;
          cur.wx = j;
          F[i][j] = 0;
        } else if (F[i][j] == 2) {
          cur.cy = i;
          cur.cx = j;
          F[i][j] = 0;
        } else if (F[i][j] == 3) {
          gy = i;
          gx = j;
          F[i][j] = 0;
        }
      }
    cout << bfs(cur) << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

#define MAX_H 7
#define MAX_W 7

int w, h;
int gy, gx;
int F[MAX_H][MAX_W];

struct P {
  int wx, wy;
  int cx, cy;
  int t;
};

const int dy[] = {0, 1, 0, -1};
const int dx[] = {1, 0, -1, 0};
bool used[MAX_H][MAX_W][MAX_H][MAX_W]; // 荷物の座標, ミスターの座標

bool v[MAX_H][MAX_W];
bool can_move_to(int fy, int fx, int ty, int tx) {
  if (ty == fy && tx == fx)
    return true;
  if (F[fy][fx] == 1)
    return false;
  for (int i = 0; i < 4; i++) {
    int ny = fy + dy[i];
    int nx = fx + dx[i];
    if (0 <= ny && ny < h && 0 <= nx && nx < w && !v[ny][nx]) {
      v[fy][fx] = true;
      if (can_move_to(ny, nx, ty, tx))
        return true;
    }
  }
  return false;
}

int bfs(P cur) {
  queue<P> q;
  q.push(cur);
  memset(used, 0, sizeof(used));
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    if (p.cy == gy && p.cx == gx)
      return p.t;
    for (int i = 0; i < 4; i++) {
      int ny = p.cy + dy[i];
      int nx = p.cx + dx[i];
      int py = p.cy - dy[i];
      int px = p.cx - dx[i];
      P next;
      next.wy = p.cy;
      next.wx = p.cx;
      next.cy = ny;
      next.cx = nx;
      next.t = p.t + 1;
      if (0 <= ny && ny < h && 0 <= nx && nx < w && 0 <= py && py < h &&
          0 <= px && px < w && F[ny][nx] != 1 &&
          !used[next.cy][next.cx][next.wy][next.wx]) {
        memset(v, 0, sizeof(v));
        F[p.cy][p.cx] = 1;
        if (can_move_to(p.wy, p.wx, p.cy - dy[i], p.cx - dx[i]))
          q.push(next);
        F[p.cy][p.cx] = 0;
      }
    }
  }
  return -1;
}

int main() {
  while (cin >> w >> h, w || h) {
    P cur;
    cur.t = 0;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        cin >> F[i][j];
        if (F[i][j] == 4) {
          cur.wy = i;
          cur.wx = j;
        } else if (F[i][j] == 2) {
          cur.cy = i;
          cur.cx = j;
          F[i][j] = 0;
        } else if (F[i][j] == 3) {
          gy = i;
          gx = j;
        }
      }
    cout << bfs(cur) << endl;
  }
  return 0;
}