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

#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct P {
  int x;
  int y;
};

struct St {
  P mp;
  P cp;
  int cost;
};

int xdir[4] = {0, 1, 0, -1}, ydir[4] = {1, 0, -1, 0};

bool mbfs(int a[8][8], int w, int h, P mn, P cg, int gy, int gx) {
  bool f = false;
  queue<P> que;
  P p, q;
  bool vis[8][8];
  fill(&vis[0][0], &vis[7][7], true);
  vis[mn.y][mn.x] = false;
  que.push(mn);

  while (!que.empty()) {
    p = que.front();
    que.pop();
    if (p.x == gx && p.y == gy) {
      f = true;
      break;
    }

    for (int i = 0; i < 4; i++) {
      q.x = p.x + xdir[i];
      q.y = p.y + ydir[i];
      if (0 <= q.x && q.x < w && 0 <= q.y && q.y < h && a[q.y][q.x] != 1 &&
          !(q.y == cg.y && q.x == cg.x)) {
        if (vis[q.y][q.x]) {
          vis[q.y][q.x] = false;
          que.push(q);
        }
      }
    }
  }

  return f;
}

int bfs(int a[8][8], int w, int h, P mn, P cg) {
  int r = -1;
  queue<St> que;
  bool vis[8][8][8][8];
  St st1, st2;
  st1.mp = mn;
  st1.cp = cg;
  st1.cost = 0;
  que.push(st1);
  fill(&vis[0][0][0][0], &vis[7][7][7][7], true);

  while (!que.empty()) {
    st1 = que.front();
    que.pop();
    if (a[st1.cp.y][st1.cp.x] == 3) {
      r = st1.cost;
      break;
    }

    for (int i = 0; i < 4; i++) {
      int dx = st1.cp.x + xdir[i];
      int dy = st1.cp.y + ydir[i];
      int mdx = st1.cp.x - xdir[i];
      int mdy = st1.cp.y - ydir[i];

      if (0 <= dx && dx < w && 0 <= dy && dy < h && a[dy][dx] != 1) {
        if (0 <= mdx && mdx < w && 0 <= mdy && mdy < h && a[mdy][mdx] != 1 &&
            vis[mdy][mdx][st1.cp.y][st1.cp.x]) {
          if (mbfs(a, w, h, st1.mp, st1.cp, mdy, mdx)) {
            vis[mdy][mdx][st1.cp.y][st1.cp.x] = false;
            st2.cp.y = dy;
            st2.cp.x = dx;
            st2.mp = st1.cp;
            st2.cost = st1.cost + 1;
            que.push(st2);
          }
        }
      }
    }
  }

  return r;
}

int main() {
  int w, h, a[8][8];
  P mn, cg;

  while (cin >> w >> h && (w + h)) {
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> a[i][j];
        if (a[i][j] == 2) {
          cg.x = j;
          cg.y = i;
        } else if (a[i][j] == 4) {
          mn.x = j;
          mn.y = i;
        }
      }
    }

    cout << bfs(a, w, h, mn, cg) << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>

using namespace std;

struct P {
  int x;
  int y;
};

struct St {
  P mp;
  P cp;
  int cost;
};

int xdir[4] = {0, 1, 0, -1}, ydir[4] = {1, 0, -1, 0};

void visCheck(int a[8][8], bool vis[8][8][8][8], int w, int h, P mn, P cg) {
  P p, q;
  queue<P> que;
  que.push(mn);
  vis[cg.y][cg.x][mn.y][mn.x] = true;

  while (!que.empty()) {
    p = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      q.x = p.x + xdir[i];
      q.y = p.y + ydir[i];
      if (0 <= q.x && q.x < w && 0 <= q.y && q.y < h && a[q.y][q.x] != 1 &&
          !(q.y == cg.y && q.x == cg.x) && !vis[cg.y][cg.x][q.y][q.x]) {
        vis[cg.y][cg.x][q.y][q.x] = true;
        que.push(q);
      }
    }
  }

  return;
}

int bfs(int a[8][8], int w, int h, P gl, P mn, P cg) {
  int r = -1;
  queue<St> que;
  bool vis[8][8][8][8];
  St st1, st2;
  st1.mp = mn;
  st1.cp = cg;
  st1.cost = 0;

  que.push(st1);
  while (!que.empty()) {
    st1 = que.front();
    que.pop();
    if (st1.cp.x == gl.x && st1.cp.y == gl.y) {
      r = st1.cost;
      break;
    } else if (st1.cost > 100) {
      break;
    }
    fill(&vis[0][0][0][0], &vis[7][7][7][7], false);
    visCheck(a, vis, w, h, st1.mp, st1.cp);

    for (int i = 0; i < 4; i++) {
      st2.cp.x = st1.cp.x + xdir[i];
      st2.cp.y = st1.cp.y + ydir[i];
      if (0 <= st2.cp.x && st2.cp.x < w && 0 <= st2.cp.y && st2.cp.y < h &&
          a[st2.cp.y][st2.cp.x] != 1) {
        P p;
        p.x = st1.cp.x - xdir[i];
        p.y = st1.cp.y - ydir[i];
        if (vis[st1.cp.y][st1.cp.x][p.y][p.x]) {
          st2.mp = st1.cp;
          st2.cost = st1.cost + 1;
          que.push(st2);
        }
      }
    }
  }

  return r;
}

int main() {
  int w, h, a[8][8];
  P gl, mn, cg;

  while (cin >> w >> h && (w + h)) {
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> a[i][j];
        if (a[i][j] == 2) {
          cg.x = j;
          cg.y = i;
        } else if (a[i][j] == 3) {
          gl.x = j;
          gl.y = i;
        } else if (a[i][j] == 4) {
          mn.x = j;
          mn.y = i;
        }
      }
    }

    cout << bfs(a, w, h, gl, mn, cg) << endl;
  }

  return 0;
}