Problem p00725 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
typedef long long ll;

int w, h;

struct t_node {
  int f[20][20];
  int x, y;
  int d;
  t_node() { d = 0; }
  t_node(const t_node &tn) {
    rep(dy, h) {
      rep(dx, w) { f[dx][dy] = tn.f[dx][dy]; }
    }
    x = tn.x;
    y = tn.y;
    d = tn.d;
  }
  t_node &operator=(const t_node &r) {
    rep(dy, h) {
      rep(dx, w) { f[dx][dy] = r.f[dx][dy]; }
    }
    d = r.d;
    x = r.x;
    y = r.y;
    return *this;
  }
  bool check(int dx, int dy, int &nx, int &ny) {
    nx = x;
    ny = y;
    while (0 <= nx + dx && nx + dx < w && 0 <= ny + dy && ny + dy < h) {
      if (f[nx + dx][ny + dy] == 1) {
        return true;
      }
      nx += dx;
      ny += dy;
      if (f[nx][ny] == 3) {
        return true;
      }
    }
    return false;
  }
};

int main() {
  while (cin >> w >> h, w || h) {
    t_node tn;
    rep(y, h) {
      rep(x, w) {
        cin >> tn.f[x][y];
        if (tn.f[x][y] == 2) {
          tn.f[x][y] = 0;
          tn.x = x;
          tn.y = y;
        }
      }
    }
    queue<t_node> que;
    que.push(tn);
    bool found = false;
    while (!que.empty()) {
      tn = que.front();
      que.pop();
      if (tn.f[tn.x][tn.y] == 3) {
        found = true;
        cout << tn.d << endl;
        break;
      }
      if (tn.d == 10) {
        continue;
      }
      int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
      int nx, ny;
      rep(i, 4) {
        if (tn.f[tn.x + dx[i]][tn.y + dy[i]] != 1 &&
            tn.check(dx[i], dy[i], nx, ny)) {
          bool flg = (tn.f[nx + dx[i]][ny + dy[i]] == 1);
          if (flg) {
            tn.f[nx + dx[i]][ny + dy[i]] = 0;
          }
          tn.d++;
          int tmpx = tn.x, tmpy = tn.y;
          tn.x = nx;
          tn.y = ny;
          que.push(tn);
          tn.x = tmpx;
          tn.y = tmpy;
          tn.d--;
          if (flg) {
            tn.f[nx + dx[i]][ny + dy[i]] = 1;
          }
        }
      }
    }
    if (!found) {
      cout << "-1" << endl;
    }
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
typedef long long ll;

int w, h;

struct t_node {
  short f[20][20];
  int x, y;
  int d;
  t_node() { d = 0; }
  t_node(const t_node &tn) {
    rep(dy, h) {
      rep(dx, w) { f[dx][dy] = tn.f[dx][dy]; }
    }
    x = tn.x;
    y = tn.y;
    d = tn.d;
  }
  t_node &operator=(const t_node &r) {
    rep(dy, h) {
      rep(dx, w) { f[dx][dy] = r.f[dx][dy]; }
    }
    d = r.d;
    x = r.x;
    y = r.y;
    return *this;
  }
  bool check(int dx, int dy, int &nx, int &ny) {
    nx = x;
    ny = y;
    while (0 <= nx + dx && nx + dx < w && 0 <= ny + dy && ny + dy < h) {
      if (f[nx + dx][ny + dy] == 1) {
        return true;
      }
      nx += dx;
      ny += dy;
      if (f[nx][ny] == 3) {
        return true;
      }
    }
    return false;
  }
};

int main() {
  while (cin >> w >> h, w || h) {
    t_node tn;
    rep(y, h) {
      rep(x, w) {
        cin >> tn.f[x][y];
        if (tn.f[x][y] == 2) {
          tn.f[x][y] = 0;
          tn.x = x;
          tn.y = y;
        }
      }
    }
    queue<t_node> que;
    que.push(tn);
    bool found = false;
    while (!que.empty()) {
      tn = que.front();
      que.pop();
      if (tn.f[tn.x][tn.y] == 3) {
        found = true;
        cout << tn.d << endl;
        break;
      }
      if (tn.d == 10) {
        continue;
      }
      int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
      int nx, ny;
      rep(i, 4) {
        if (tn.f[tn.x + dx[i]][tn.y + dy[i]] != 1 &&
            tn.check(dx[i], dy[i], nx, ny)) {
          bool flg = (tn.f[nx + dx[i]][ny + dy[i]] == 1);
          if (flg) {
            tn.f[nx + dx[i]][ny + dy[i]] = 0;
          }
          tn.d++;
          int tmpx = tn.x, tmpy = tn.y;
          tn.x = nx;
          tn.y = ny;
          que.push(tn);
          tn.x = tmpx;
          tn.y = tmpy;
          tn.d--;
          if (flg) {
            tn.f[nx + dx[i]][ny + dy[i]] = 1;
          }
        }
      }
    }
    if (!found) {
      cout << "-1" << endl;
    }
  }
  return 0;
}