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

#include <bits/stdc++.h>

using namespace std;

typedef pair<short, short> P;

const int INF = 1 << 29;

inline int dist(const P &a, const P &b) {
  return abs(a.first - b.first) + abs(a.second - b.second);
}

int dp[6][1024];

int main() {
  int w, h;
  while (scanf("%d %d", &w, &h), w) {
    vector<P> ps[5];

    P start, goal;
    for (int y = 0; y < h; y++) {
      char line[1024];
      scanf("%s", line);
      for (int x = 0; x < w; x++) {
        if (line[x] == 'S')
          start = P(x, y);
        else if (line[x] == 'G')
          goal = P(x, y);
        else if (line[x] != '.') {
          int id = line[x] - '1';
          ps[id].push_back(P(x, y));
        }
      }
    }
    int mini = INF;
    int mini_id = -1;
    for (int init = 0; init < 5; init++) {
      for (int i = 0; i < 6; i++)
        for (int j = 0; j < 1024; j++)
          dp[i][j] = INF;
      int nxt = (init + 1) % 5;
      for (int i = 0; i < ps[nxt].size(); i++) {
        dp[0][i] = dist(start, ps[nxt][i]);
      }
      for (int i = 1; i < 4; i++) {
        int nnxt = (nxt + 1) % 5;
        for (int j = 0; j < ps[nxt].size(); j++) {
          for (int k = 0; k < ps[nnxt].size(); k++) {
            dp[i][k] =
                min(dp[i][k], dp[i - 1][j] + dist(ps[nxt][j], ps[nnxt][k]));
          }
        }
        nxt = nnxt;
      }
      for (int i = 0; i < ps[nxt].size(); i++) {
        int value = dp[3][i] + dist(ps[nxt][i], goal);
        if (mini > value) {
          mini = dp[3][i] + dist(ps[nxt][i], goal);
          mini_id = init;
        }
      }
    }
    if (mini == INF)
      printf("NA\\n");
    else
      printf("%d %d\\n", mini_id + 1, mini);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef pair<short, short> P;

const int MAX_V = 5003;
const int INF = 1 << 29;

int cost[MAX_V][MAX_V];
int d[MAX_V];
bool used[MAX_V];
int V;

void dijkstra(int s) {
  fill(d, d + V, INF);
  fill(used, used + V, false);
  d[s] = 0;
  while (true) {
    int v = -1;
    for (int u = 0; u < V; u++) {
      if (!used[u] && (v == -1 || d[v] < d[v]))
        v = u;
    }
    if (v == -1)
      break;
    used[v] = true;
    for (int u = 0; u < V; u++) {
      d[u] = min(d[u], d[v] + cost[v][u]);
    }
  }
}

inline int dist(const P &a, const P &b) {
  return abs(a.first - b.first) + abs(a.second - b.second);
}

P ps[5][1024];
short is[5][1024];
short psl[5], isl[5];

int main() {
  int w, h;
  while (scanf("%d %d", &w, &h), w) {
    memset(psl, 0, sizeof(psl));
    memset(isl, 0, sizeof(isl));

    P start, goal;
    for (int y = 0; y < h; y++) {
      char line[1024];
      scanf("%s", line);
      for (int x = 0; x < w; x++) {
        if (line[x] == 'S')
          start = P(x, y);
        else if (line[x] == 'G')
          goal = P(x, y);
        else if (line[x] != '.') {
          int id = line[x] - '1';
          ps[id][psl[id]++] = P(x, y);
        }
      }
    }
    V = 2;
    for (int i = 0; i < 5; i++) {
      for (int p = 0; p < psl[i]; p++) {
        is[i][isl[i]++] = V++;
      }
    }
    int mini = INF;
    int mini_id = -1;
    for (int i = 0; i < MAX_V; i++) {
      for (int j = 0; j < MAX_V; j++) {
        cost[i][j] = INF;
      }
    }
    for (int init = 0; init < 5; init++) {
      int nxt = (init + 1) % 5;
      for (int i = 0; i < psl[nxt]; i++) {
        cost[0][is[nxt][i]] = dist(start, ps[nxt][i]);
      }
      for (int i = 0; i < 3; i++) {
        int nnxt = (nxt + 1) % 5;
        for (int j = 0; j < psl[nxt]; j++) {
          for (int k = 0; k < psl[nnxt]; k++) {
            cost[is[nxt][j]][is[nnxt][k]] = dist(ps[nxt][j], ps[nnxt][k]);
          }
        }
        nxt = nnxt;
      }
      for (int i = 0; i < psl[nxt]; i++) {
        cost[is[nxt][i]][1] = dist(goal, ps[nxt][i]);
      }
      dijkstra(0);
      if (mini > d[1]) {
        mini = d[1];
        mini_id = init;
      }
    }
    if (mini_id == -1)
      puts("NA");
    else
      printf("%d %d\\n", mini_id + 1, mini);
  }
  return 0;
}