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

#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
using namespace std;

typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<int, PP> PPP;
typedef pair<int, PPP> E;
typedef priority_queue<E, vector<E>, greater<E>> Q;

int M, N, D;
int sr, sc;
int gr, gc;
int cost_c[19][20];
int cost_r[20][19];
int signal[20][20];
bool used[101][4][20][20];
const int INF = 10000000;

bool input() {
  scanf("%d %d\\n", &M, &N);
  if (!M && !N) {
    return false;
  }
  scanf("%d\\n", &D);
  for (int i = 0; i < M - 1; ++i) {
    for (int j = 0; j < N; ++j) {
      cost_c[i][j] = D;
    }
  }
  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < N - 1; ++j) {
      cost_r[i][j] = D;
    }
  }
  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < N; ++j) {
      signal[i][j] = -1;
    }
  }
  int ns;
  scanf("%d\\n", &ns);
  for (int i = 0; i < ns; ++i) {
    char a;
    int r, c, k;
    scanf("%c-%d %d\\n", &a, &c, &k);
    r = a - 'a';
    --c;
    signal[r][c] = k;
  }
  int nc;
  scanf("%d\\n", &nc);
  for (int i = 0; i < nc; ++i) {
    char a1, a2;
    int r1, c1, r2, c2;
    scanf("%c-%d %c-%d\\n", &a1, &c1, &a2, &c2);
    r1 = a1 - 'a';
    r2 = a2 - 'a';
    --c1;
    --c2;
    if (r1 == r2) {
      cost_r[r1][min(c1, c2)] = INF;
    } else if (c1 == c2) {
      cost_c[min(r1, r2)][c1] = INF;
    }
  }
  int nj;
  scanf("%d\\n", &nj);
  for (int i = 0; i < nj; ++i) {
    char a1, a2;
    int r1, c1, r2, c2, d;
    scanf("%c-%d %c-%d %d\\n", &a1, &c1, &a2, &c2, &d);
    r1 = a1 - 'a';
    r2 = a2 - 'a';
    --c1;
    --c2;
    if (r1 == r2) {
      cost_r[r1][min(c1, c2)] += d;
    } else if (c1 == c2) {
      cost_c[min(r1, r2)][c1] += d;
    }
  }
  {
    char c;
    scanf("%c-%d\\n", &c, &sc);
    sr = c - 'a';
    --sc;
  }
  {
    char c;
    scanf("%c-%d\\n", &c, &gc);
    gr = c - 'a';
    --gc;
  }
  for (int t = 0; t <= 100; ++t) {
    for (int d = 0; d < 4; ++d) {
      for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
          used[t][d][i][j] = false;
        }
      }
    }
  }
  return true;
}

bool can_go(int t, int k, bool row) {
  int h = t / k;
  if (row) {
    return h & 1;
  } else {
    return !(h & 1);
  }
}

int solve() {
  PP s = PP(0, P(sr, sc));
  int h0 = (abs(sr - gr) + abs(sc - gc)) * D;
  Q q;
  q.push(E(h0, PPP(0, s)));
  int ans = -1;
  while (!q.empty()) {
    E cur = q.top();
    q.pop();
    PPP ppp = cur.second;
    int t = ppp.first;
    PP pp = ppp.second;
    int d = pp.first;
    P p = pp.second;
    int r = p.first;
    int c = p.second;
    if (r == gr && c == gc) {
      ans = t;
      break;
    }
    if (used[t][d][r][c]) {
      continue;
    }
    used[t][d][r][c] = true;
    if (r > 0 && d != 2) {
      int nt = t + cost_c[r - 1][c];
      if (nt < INF &&
          (signal[r - 1][c] < 0 || can_go(nt, signal[r - 1][c], false))) {
        int h = (abs(r - 1 - gr) + abs(c - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(3, P(r - 1, c)))));
      }
    }
    if (r < M - 1 && d != 3) {
      int nt = t + cost_c[r][c];
      if (nt < INF &&
          (signal[r + 1][c] < 0 || can_go(nt, signal[r + 1][c], false))) {
        int h = (abs(r + 1 - gr) + abs(c - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(2, P(r + 1, c)))));
      }
    }
    if (c > 0 && d != 0) {
      int nt = t + cost_r[r][c - 1];
      if (nt < INF &&
          (signal[r][c - 1] < 0 || can_go(nt, signal[r][c - 1], true))) {
        int h = (abs(r - gr) + abs(c - 1 - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(1, P(r, c - 1)))));
      }
    }
    if (c < N - 1 && d != 1) {
      int nt = t + cost_r[r][c];
      if (nt < INF &&
          (signal[r][c + 1] < 0 || can_go(nt, signal[r][c + 1], true))) {
        int h = (abs(r - gr) + abs(c + 1 - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(0, P(r, c + 1)))));
      }
    }
  }
  return ans;
}

int main() {
  while (input()) {
    int ans = solve();
    printf("%d\\n", ans);
  }
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
using namespace std;

typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<int, PP> PPP;
typedef pair<int, PPP> E;
typedef priority_queue<E, vector<E>, greater<E>> Q;

int M, N, D;
int sr, sc;
int gr, gc;
int cost_c[19][20];
int cost_r[20][19];
int signal[20][20];
const int INF = 10000000;

bool input() {
  scanf("%d %d\\n", &M, &N);
  if (!M && !N) {
    return false;
  }
  scanf("%d\\n", &D);
  for (int i = 0; i < M - 1; ++i) {
    for (int j = 0; j < N; ++j) {
      cost_c[i][j] = D;
    }
  }
  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < N - 1; ++j) {
      cost_r[i][j] = D;
    }
  }
  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < N; ++j) {
      signal[i][j] = -1;
    }
  }
  int ns;
  scanf("%d\\n", &ns);
  for (int i = 0; i < ns; ++i) {
    char a;
    int r, c, k;
    scanf("%c-%d %d\\n", &a, &c, &k);
    r = a - 'a';
    --c;
    signal[r][c] = k;
  }
  int nc;
  scanf("%d\\n", &nc);
  for (int i = 0; i < nc; ++i) {
    char a1, a2;
    int r1, c1, r2, c2;
    scanf("%c-%d %c-%d\\n", &a1, &c1, &a2, &c2);
    r1 = a1 - 'a';
    r2 = a2 - 'a';
    --c1;
    --c2;
    if (r1 == r2) {
      cost_r[r1][min(c1, c2)] = INF;
    } else if (c1 == c2) {
      cost_c[min(r1, r2)][c1] = INF;
    }
  }
  int nj;
  scanf("%d\\n", &nj);
  for (int i = 0; i < nj; ++i) {
    char a1, a2;
    int r1, c1, r2, c2, d;
    scanf("%c-%d %c-%d %d\\n", &a1, &c1, &a2, &c2, &d);
    r1 = a1 - 'a';
    r2 = a2 - 'a';
    --c1;
    --c2;
    if (r1 == r2) {
      cost_r[r1][min(c1, c2)] += d;
    } else if (c1 == c2) {
      cost_c[min(r1, r2)][c1] += d;
    }
  }
  {
    char c;
    scanf("%c-%d\\n", &c, &sc);
    sr = c - 'a';
    --sc;
  }
  {
    char c;
    scanf("%c-%d\\n", &c, &gc);
    gr = c - 'a';
    --gc;
  }
  return true;
}

bool can_go(int t, int k, bool row) {
  int h = t / k;
  if (row) {
    return h & 1;
  } else {
    return !(h & 1);
  }
}

int solve() {
  PP s = PP(0, P(sr, sc));
  int h0 = (abs(sr - gr) + abs(sc - gc)) * D;
  Q q;
  q.push(E(h0, PPP(0, s)));
  int ans = -1;
  while (!q.empty()) {
    E cur = q.top();
    q.pop();
    PPP ppp = cur.second;
    int t = ppp.first;
    PP pp = ppp.second;
    int d = pp.first;
    P p = pp.second;
    int r = p.first;
    int c = p.second;
    if (r == gr && c == gc) {
      ans = t;
      break;
    }
    if (r > 0 && d != 2) {
      int nt = t + cost_c[r - 1][c];
      if (nt < INF &&
          (signal[r - 1][c] < 0 || can_go(nt, signal[r - 1][c], false))) {
        int h = (abs(r - 1 - gr) + abs(c - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(3, P(r - 1, c)))));
      }
    }
    if (r < M - 1 && d != 3) {
      int nt = t + cost_c[r][c];
      if (nt < INF &&
          (signal[r + 1][c] < 0 || can_go(nt, signal[r + 1][c], false))) {
        int h = (abs(r + 1 - gr) + abs(c - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(2, P(r + 1, c)))));
      }
    }
    if (c > 0 && d != 0) {
      int nt = t + cost_r[r][c - 1];
      if (nt < INF &&
          (signal[r][c - 1] < 0 || can_go(nt, signal[r][c - 1], true))) {
        int h = (abs(r - gr) + abs(c - 1 - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(1, P(r, c - 1)))));
      }
    }
    if (c < N - 1 && d != 1) {
      int nt = t + cost_r[r][c];
      if (nt < INF &&
          (signal[r][c + 1] < 0 || can_go(nt, signal[r][c + 1], true))) {
        int h = (abs(r - gr) + abs(c + 1 - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(0, P(r, c + 1)))));
      }
    }
  }
  return ans;
}

int main() {
  while (input()) {
    int ans = solve();
    printf("%d\\n", ans);
  }
}