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

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <set>
#include <vector>

#define MAX 21

#define INV (-1)
#define ALL 0
#define SN 1
#define WE 2

#define NA 100

const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

using namespace std;

bool isinside(int i, int j, int m, int n) {
  return 0 <= i && i < m && 0 <= j && j < n;
}

class Signal {
public:
  bool sig[MAX][MAX]; // allowable pass direction
  int sig_freq[MAX][MAX];

  Signal() {
    for (int i = 0; i < MAX; ++i) {
      for (int j = 0; j < MAX; ++j) {
        sig[i][j] = false;
        sig_freq[i][j] = 0;
      }
    }
  }

  bool getEnterableAt(int fromi, int fromj, int i, int j, int t) const {
    if (!sig[i][j])
      return true;
    else {
      int dir = (fromi == i ? SN : WE);
      int div = t / sig_freq[i][j];
      if (div % 2 == 1)
        return dir == SN;
      else
        return dir == WE;
    }
  }
};

class State {
public:
  int prei, prej;
  int i, j;
  int cost;
  State() : i(0), j(0), cost(0) {}
  State(int pi, int pj, int i, int j, int cost)
      : prei(pi), prej(pj), i(i), j(j), cost(cost) {}
  bool operator>(const State &t) const { return cost > t.cost; }
};

bool adj[MAX][MAX][MAX][MAX];
int add[MAX][MAX][MAX][MAX];

void ResetGraph() {
  for (int i = 0; i < MAX; ++i) {
    for (int j = 0; j < MAX; ++j) {
      for (int k = 0; k < MAX; ++k) {
        for (int l = 0; l < MAX; ++l) {
          adj[i][j][k][l] = true;
          add[i][j][k][l] = 0;
        }
      }
    }
  }
}

int getShortestTime(int m, int n, int D, int si, int sj, int gi, int gj,
                    const Signal &sig) {
  State init(si, sj, si, sj, 0);
  priority_queue<State, vector<State>, greater<State>> q;

  static bool vis[MAX][MAX][MAX][MAX][101];
  fill(&vis[0][0][0][0][0], &vis[MAX - 1][MAX - 1][MAX - 1][MAX - 1][100],
       false);

  q.push(init);
  while (!q.empty()) {

    State now = q.top();
    q.pop();

    // cout << "(" << now.i << ',' << now.j << "), from (" << now.prei << "," <<
    // now.prej << ") cost = " << now.cost << endl;

    if (now.cost + D * (abs(now.i - gi) + abs(now.j - gj)) > NA)
      continue;
    if (now.i == gi && now.j == gj)
      return now.cost;

    if (vis[now.prei][now.prej][now.i][now.j][now.cost])
      continue;
    vis[now.prei][now.prej][now.i][now.j][now.cost] = true;

    for (int k = 0; k < sizeof(di) / sizeof(*di); ++k) {

      int ti = now.i + di[k];
      int tj = now.j + dj[k];

      // cout << "(" << ti << ',' << tj << ")" << endl;

      if (!isinside(ti, tj, m, n))
        continue;
      if (ti == now.prei && tj == now.prej)
        continue;
      if (!adj[now.i][now.j][ti][tj])
        continue;

      int ncost = now.cost + D + add[now.i][now.j][ti][tj];
      if (!sig.getEnterableAt(now.i, now.j, ti, tj, ncost))
        continue;

      q.push(State(now.i, now.j, ti, tj, ncost));
    }
  }

  return -1;
}

int main() {
  while (true) {
    int M, N;
    Signal sigs;
    cin >> M >> N;
    if (M == 0 && N == 0)
      break;

    ResetGraph();

    int D;
    cin >> D;
    int ns;
    cin >> ns;
    for (int i = 0; i < ns; ++i) {
      char y, c;
      int x, k;
      cin >> y >> c >> x >> k;
      y -= 'a';
      x--;

      sigs.sig[y][x] = true;
      sigs.sig_freq[y][x] = k;
    }
    int nc;
    cin >> nc;
    for (int i = 0; i < nc; ++i) {
      char y, c, y2;
      int x, x2;
      cin >> y >> c >> x >> y2 >> c >> x2;
      y -= 'a';
      y2 -= 'a';
      --x;
      --x2;

      adj[y][x][y2][x2] = false;
      adj[y2][x2][y][x] = false;
    }
    int nj;
    cin >> nj;
    for (int i = 0; i < nj; ++i) {
      char y, c, y2;
      int x, x2;
      int d;
      cin >> y >> c >> x >> y2 >> c >> x2 >> d;
      y -= 'a';
      y2 -= 'a';
      --x;
      --x2;

      add[y][x][y2][x2] = d;
      add[y2][x2][y][x] = d;
    }

    char sy, gy, c;
    int sx, gx;
    cin >> sy >> c >> sx >> gy >> c >> gx;
    sy -= 'a';
    --sx;
    gy -= 'a';
    --gx;

    cout << getShortestTime(M, N, D, sy, sx, gy, gx, sigs) << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <set>
#include <vector>

#define MAX 32

#define INV (-1)
#define ALL 0
#define SN 1
#define WE 2

#define NA 100

const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

using namespace std;

bool isinside(int i, int j, int m, int n) {
  return 0 <= i && i < m && 0 <= j && j < n;
}

class Signal {
public:
  bool sig[MAX][MAX]; // allowable pass direction
  int sig_freq[MAX][MAX];

  Signal() {
    for (int i = 0; i < MAX; ++i) {
      for (int j = 0; j < MAX; ++j) {
        sig[i][j] = false;
        sig_freq[i][j] = 0;
      }
    }
  }

  bool getEnterableAt(int fromi, int fromj, int i, int j, int t) const {
    if (!sig[i][j])
      return true;
    else {
      int dir = (fromi == i ? SN : WE);
      int div = t / sig_freq[i][j];
      if (div % 2 == 1)
        return dir == SN;
      else
        return dir == WE;
    }
  }
};

class State {
public:
  int prei, prej;
  int i, j;
  int cost;
  State() : i(0), j(0), cost(0) {}
  State(int pi, int pj, int i, int j, int cost)
      : prei(pi), prej(pj), i(i), j(j), cost(cost) {}
  bool operator>(const State &t) const { return cost > t.cost; }
};

bool adj[MAX][MAX][MAX][MAX];
int add[MAX][MAX][MAX][MAX];

void ResetGraph() {
  for (int i = 0; i < MAX; ++i) {
    for (int j = 0; j < MAX; ++j) {
      for (int k = 0; k < MAX; ++k) {
        for (int l = 0; l < MAX; ++l) {
          adj[i][j][k][l] = true;
          add[i][j][k][l] = 0;
        }
      }
    }
  }
}

int getShortestTime(int m, int n, int D, int si, int sj, int gi, int gj,
                    const Signal &sig) {
  State init(-1, -1, si, sj, 0);
  priority_queue<State, vector<State>, greater<State>> q;

  q.push(init);
  while (!q.empty()) {

    State now = q.top();
    q.pop();

    // cout << "(" << now.i << ',' << now.j << "), from (" << now.prei << "," <<
    // now.prej << ") cost = " << now.cost << endl;

    if (now.cost + D * (abs(now.i - gi) + abs(now.j - gj)) > NA)
      continue;
    if (now.i == gi && now.j == gj)
      return now.cost;

    for (int k = 0; k < sizeof(di) / sizeof(*di); ++k) {

      int ti = now.i + di[k];
      int tj = now.j + dj[k];

      // cout << "(" << ti << ',' << tj << ")" << endl;
      /* dijkstra */

      if (!isinside(ti, tj, m, n))
        continue;
      if (ti == now.prei && tj == now.prej)
        continue;
      if (!adj[now.i][now.j][ti][tj])
        continue;

      int ncost = now.cost + D + add[now.i][now.j][ti][tj];
      if (!sig.getEnterableAt(now.i, now.j, ti, tj, ncost))
        continue;

      q.push(State(now.i, now.j, ti, tj, ncost));
    }
  }

  return -1;
}

int main() {
  while (true) {
    int M, N;
    Signal sigs;
    cin >> M >> N;
    if (M == 0 && N == 0)
      break;

    ResetGraph();

    int D;
    cin >> D;
    int ns;
    cin >> ns;
    for (int i = 0; i < ns; ++i) {
      char y, c;
      int x, k;
      cin >> y >> c >> x >> k;
      y -= 'a';
      x--;

      sigs.sig[y][x] = true;
      sigs.sig_freq[y][x] = k;
    }
    int nc;
    cin >> nc;
    for (int i = 0; i < nc; ++i) {
      char y, c, y2;
      int x, x2;
      cin >> y >> c >> x >> y2 >> c >> x2;
      y -= 'a';
      y2 -= 'a';
      --x;
      --x2;

      adj[y][x][y2][x2] = false;
      adj[y2][x2][y][x] = false;
    }
    int nj;
    cin >> nj;
    for (int i = 0; i < nj; ++i) {
      char y, c, y2;
      int x, x2;
      int d;
      cin >> y >> c >> x >> y2 >> c >> x2 >> d;
      y -= 'a';
      y2 -= 'a';
      --x;
      --x2;

      add[y][x][y2][x2] = d;
      add[y2][x2][y][x] = d;
    }

    char sy, gy, c;
    int sx, gx;
    cin >> sy >> c >> sx >> gy >> c >> gx;
    sy -= 'a';
    --sx;
    gy -= 'a';
    --gx;

    cout << getShortestTime(M, N, D, sy, sx, gy, gx, sigs) << endl;
  }
  return 0;
}