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

#include <iostream>
#include <vector>

using namespace std;

#define dump(n) cerr << "# " << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

ostream &operator<<(ostream &os, const pii &a) {
  return os << '(' << a.first << ',' << a.second << ')';
}

int getdist(pii a, pii b) {
  return abs(a.first - b.first) + abs(a.second - b.second);
}

int main() {
  for (int w, h; cin >> w >> h, w | h;) {
    vs grid(h);
    rep(i, h) cin >> grid[i];

    pii start, goal;
    vector<vector<pii>> ps(5);
    rep(i, h) rep(j, w) {
      if (grid[i][j] == 'S')
        start = pii(i, j);
      if (grid[i][j] == 'G')
        goal = pii(i, j);
      if (isdigit(grid[i][j]))
        ps[grid[i][j] - '1'].emplace_back(i, j);
    }

    vvi dp(5);
    rep(i, 5) dp[i].resize(ps[i].size());

    pii res(INFTY, -1);
    rep(f, 5) {
      rep(i, 5) fill(all(dp[i]), INFTY);
      rep(i, dp[(f + 1) % 5].size()) dp[(f + 1) % 5][i] =
          getdist(start, ps[(f + 1) % 5][i]);
      repi(i, 2, 5) {
        vector<pii> &ps0 = ps[(f + i - 1) % 5], &ps1 = ps[(f + i) % 5];
        vi &dp0 = dp[(f + i - 1) % 5], &dp1 = dp[(f + i) % 5];
        rep(j, dp0.size()) rep(k, dp1.size()) dp1[k] =
            min(dp1[k], dp0[j] + getdist(ps0[j], ps1[k]));
      }
      int tmp = INFTY;
      rep(i, dp[(f + 4) % 5].size()) tmp =
          min(tmp, dp[(f + 4) % 5][i] + getdist(ps[(f + 4) % 5][i], goal));
      res = min(res, pii(tmp, f));
    }
    if (res.second == -1)
      cout << "NA" << endl;
    else
      cout << res.second + 1 << ' ' << res.first << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>

using namespace std;

#define dump(n) cerr << "# " << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;

struct State {
  int i, j, cost, bit;
  State() {}
  State(int i, int j, int c, int b) : i(i), j(j), cost(c), bit(b) {}
};

int solve(vs &grid, pii start, pii goal, int firstbit) {
  int h = grid.size(), w = grid[0].size();
  vector<vvi> vis(h, vvi(w, vi(1 << 5)));
  queue<State> q;
  q.push(State(start.first, start.second, 0, firstbit));
  while (q.size()) {
    State cur = q.front();
    q.pop();

    if (cur.bit == 31 && mp(cur.i, cur.j) == goal)
      return cur.cost;
    if (vis[cur.i][cur.j][cur.bit])
      continue;
    vis[cur.i][cur.j][cur.bit] = 1;

    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};
    rep(k, 4) {
      int ni = cur.i + di[k], nj = cur.j + dj[k];
      if (ni < 0 || h <= ni || nj < 0 || w <= nj)
        continue;
      if (grid[ni][nj] == '.')
        q.push(State(ni, nj, cur.cost + 1, cur.bit));
      else {
        int m = grid[ni][nj] - '1';
        if (cur.bit & (1 << (m + 4) % 5))
          q.push(State(ni, nj, cur.cost + 1, cur.bit | 1 << m));
        else
          q.push(State(ni, nj, cur.cost + 1, cur.bit));
      }
    }
  }
  return INFTY;
}

int main() {
  for (int w, h; cin >> w >> h, w | h;) {
    vs grid(h);
    rep(i, h) cin >> grid[i];

    pii start, goal;
    rep(i, h) rep(j, w) {
      if (grid[i][j] == 'S') {
        start = mp(i, j);
        grid[i][j] = '.';
      }
      if (grid[i][j] == 'G') {
        goal = mp(i, j);
        grid[i][j] = '.';
      }
    }

    pii res(INFTY, -1);
    rep(i, 5) {
      int tmp = solve(grid, start, goal, 1 << i);
      res = min(res, mp(tmp, i));
    }

    if (res.second == -1)
      cout << "NA" << endl;
    else
      cout << res.second + 1 << ' ' << res.first << endl;
  }

  return 0;
}