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

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

#define REP(i, n) for (int i = 0; i < (int)(n); ++i)

int R, C;
const int inf = 987564321;
int sr, sc, gr, gc;

struct Edge {
  int dst, cost;
};
int memo[5010];

int dag_dp(int s, int t, int start, vector<int> X[5], vector<int> Y[5]) {
  REP(i, 5010) memo[i] = inf;
  priority_queue<pair<int, int>> up;
  up.push(make_pair(0, s));
  memo[s] = 0;
  while (!up.empty()) {
    int pos = up.top().second;
    int cost = -up.top().first;
    up.pop();
    if (pos == t)
      return cost;

    if (pos == s) {
      int n_color = (start + 1) % 5;
      for (int i = 0; i < (int)X[n_color].size(); i++) {
        int next = n_color * 1000 + i;
        int n_cost = cost + abs(sr - X[n_color][i]) + abs(sc - Y[n_color][i]);
        if (memo[next] > n_cost) {
          memo[next] = n_cost;
          up.push(make_pair(-n_cost, next));
        }
      }
    } else {
      int color = pos / 1000;
      int n_color = (color + 1) % 5;
      if (n_color == start) {
        int next = t;
        int n_cost = cost + abs(gr - X[color][pos % 1000]) +
                     abs(gc - Y[color][pos % 1000]);
        if (memo[next] > n_cost) {
          memo[next] = n_cost;
          up.push(make_pair(-n_cost, next));
        }
      } else {
        for (int i = 0; i < (int)X[n_color].size(); i++) {
          int next = n_color * 1000 + i;
          int n_cost = cost + abs(X[color][pos % 1000] - X[n_color][i]) +
                       abs(Y[color][pos % 1000] - Y[n_color][i]);
          if (memo[next] > n_cost) {
            memo[next] = n_cost;
            up.push(make_pair(-n_cost, next));
          }
        }
      }
    }
  }
  return inf;
}

int main() {
  for (;;) {
    scanf("%d%d", &C, &R);
    if (R == 0 && C == 0)
      break;

    vector<int> X[5], Y[5];

    REP(r, R) REP(c, C) {
      char ch;
      scanf(" %c", &ch);
      if (ch == 'S') {
        sr = r;
        sc = c;
      } else if (ch == 'G') {
        gr = r;
        gc = c;
      } else if (ch != '.') {
        int n = ch - '1';
        X[n].push_back(r);
        Y[n].push_back(c);
      }
    }

    pair<int, int> res(inf, -1); // à, ÅÌ®«
    REP(start, 5) {
      int s = 5000;
      int t = 5001;

      /*
        int n = (start + 1) % 5;
        REP(i, X[n].size())
        graph[s].push_back( (Edge){n * 1000 + i, abs(sr - X[n][i]) + abs(sc -
        Y[n][i]) } );

        REP(step, 3) {
        int m = (n + 1) % 5;
        REP(i, X[n].size()) REP(j, X[m].size())
        graph[n * 1000 + i].push_back( (Edge) {m * 1000 + j, abs(X[n][i] -
        X[m][j]) + abs(Y[n][i] - Y[m][j]) } ); n = m;
        }

        REP(i, X[n].size())
        graph[n * 1000 + i].push_back( (Edge){t, abs(gr - X[n][i]) + abs(gc -
        Y[n][i]) } );
      */
      int temp = dag_dp(s, t, start, X, Y);
      res = min(res, make_pair(temp, start));
    }
    if (res.second == -1)
      cout << "NA" << endl;
    else
      cout << res.second + 1 << ' ' << res.first << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

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

#define REP(i, n) for (int i = 0; i < (int)(n); ++i)

int R, C;
const int inf = 987564321;

struct Edge {
  int dst, cost;
};
vector<Edge> graph[5010];
int memo[5010];

int dag_dp(int s, int t) {
  REP(i, 5010) memo[i] = inf;
  priority_queue<pair<int, int>> up;
  up.push(make_pair(0, s));
  memo[s] = 0;
  while (!up.empty()) {
    int pos = up.top().second;
    int cost = -up.top().first;
    up.pop();
    //     cout << pos << ' ' << cost << endl;
    if (pos == t)
      return cost;
    for (int i = 0; i < (int)graph[pos].size(); i++) {
      int next = graph[pos][i].dst;
      int n_cost = cost + graph[pos][i].cost;
      if (memo[next] > n_cost) {
        memo[next] = n_cost;
        up.push(make_pair(-n_cost, next));
      }
    }
  }
  return inf;
}

int main() {
  for (;;) {
    scanf("%d%d", &C, &R);
    if (R == 0 && C == 0)
      break;

    int sr, sc, gr, gc;
    vector<int> X[5], Y[5];

    REP(r, R) REP(c, C) {
      char ch;
      scanf(" %c", &ch);
      if (ch == 'S') {
        sr = r;
        sc = c;
      } else if (ch == 'G') {
        gr = r;
        gc = c;
      } else if (ch != '.') {
        int n = ch - '1';
        X[n].push_back(r);
        Y[n].push_back(c);
      }
    }

    pair<int, int> res(inf, -1); // à, ÅÌ®«
    REP(start, 5) {
      REP(i, 5010) graph[i].clear();
      int s = 5000;
      int t = 5001;

      int n = (start + 1) % 5;
      REP(i, X[n].size())
      graph[s].push_back(
          (Edge){n * 1000 + i, abs(sr - X[n][i]) + abs(sc - Y[n][i])});

      REP(step, 3) {
        int m = (n + 1) % 5;
        REP(i, X[n].size())
        REP(j, X[m].size()) graph[n * 1000 + i].push_back((Edge){
            m * 1000 + j, abs(X[n][i] - X[m][j]) + abs(Y[n][i] - Y[m][j])});
        n = m;
      }

      REP(i, X[n].size())
      graph[n * 1000 + i].push_back(
          (Edge){t, abs(gr - X[n][i]) + abs(gc - Y[n][i])});

      int temp = dag_dp(s, t);
      res = min(res, make_pair(temp, start));
    }
    if (res.second == -1)
      cout << "NA" << endl;
    else
      cout << res.second + 1 << ' ' << res.first << endl;
  }
  return 0;
}