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

#include <bits/stdc++.h>
#define N 101
#define INF 1e9
using namespace std;
string mp[N];
int D[101][101][1 << 5];
int used[101][101];
typedef pair<int, int> P;
typedef pair<P, P> PP;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int w, h;

void bfs() {
  memset(used, -1, sizeof(used));
  queue<P> Q;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == '#')
        Q.push(P(i, j)), used[i][j] = 0;

  while (!Q.empty()) {
    P t = Q.front();
    Q.pop();
    int y = t.first;
    int x = t.second;
    for (int i = -1; i <= 1; i++)
      for (int j = -1; j <= 1; j++) {
        if (i == 0 && j == 0)
          continue;
        int nx = x + i;
        int ny = y + j;
        if (nx < 0 || ny < 0 || nx >= w || ny >= h || used[ny][nx] != -1)
          continue;
        used[ny][nx] = used[y][x] + 1;
        Q.push(P(ny, nx));
      }
  }

  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (used[i][j] == -1)
        used[i][j] = INF;
}

int visited[N][N][1 << 5];
int dijkstra(int sy, int sx) {
  map<P, int> M;
  int cnt = 0;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == 'M')
        M[P(i, j)] = cnt++;

  for (int i = 0; i < 101; i++)
    for (int j = 0; j < 101; j++)
      for (int k = 0; k < (1 << 5); k++)
        D[i][j][k] = INF;

  priority_queue<PP, vector<PP>, greater<PP>> Q;
  Q.push(PP(P(0, sy), P(sx, 0)));
  D[sy][sx][0] = 0;

  while (!Q.empty()) {
    PP t = Q.top();
    Q.pop();
    int cost = t.first.first;
    int y = t.first.second;
    int x = t.second.first;
    int bit = t.second.second;
    if (mp[y][x] == 'G' && bit == (1 << cnt) - 1)
      return cost;
    if (D[y][x][bit] < cost || visited[y][x][bit]++)
      continue;

    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      int nbit = bit;
      int ncost = cost + max(1, 4 - used[y][x]);
      if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] == '#')
        continue;
      if (D[ny][nx][nbit] <= ncost || visited[ny][nx][nbit])
        continue;
      if (mp[ny][nx] == 'M')
        nbit |= 1 << (M[P(ny, nx)]);
      Q.push(PP(P(ncost, ny), P(nx, nbit)));
      D[ny][nx][nbit] = ncost;
    }
  }
  assert(0);
}

int main() {

  cin >> w >> h;
  for (int i = 0; i < h; i++)
    cin >> mp[i];

  bfs();
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == 'S')
        cout << dijkstra(i, j) << endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define N 101
#define INF 1e9
using namespace std;
string mp[N];

int D[101][101][1 << 5];
int used[101][101];
typedef pair<int, int> P;
typedef pair<P, P> PP;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int w, h;

void bfs() {
  memset(used, -1, sizeof(used));
  queue<P> Q;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == '#')
        Q.push(P(i, j)), used[i][j] = 0;

  while (!Q.empty()) {
    P t = Q.front();
    Q.pop();
    int y = t.first;
    int x = t.second;
    for (int i = -1; i <= 1; i++)
      for (int j = -1; j <= 1; j++) {
        if (i == 0 && j == 0)
          continue;
        int nx = x + i;
        int ny = y + j;
        if (nx < 0 || ny < 0 || nx >= w || ny >= h || used[ny][nx] != -1)
          continue;
        used[ny][nx] = used[y][x] + 1;
        Q.push(P(ny, nx));
      }
  }
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      used[i][j] = max(1, used[i][j]);
}

int dijkstra(int sy, int sx) {
  map<P, int> M;
  int cnt = 0;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == 'M')
        M[P(i, j)] = cnt++;

  for (int i = 0; i < 101; i++)
    for (int j = 0; j < 101; j++)
      for (int k = 0; k < (1 << 5); k++)
        D[i][j][k] = INF;

  priority_queue<PP, vector<PP>, greater<PP>> Q;
  Q.push(PP(P(0, sy), P(sx, 0)));
  D[sy][sx][0] = 0;
  while (!Q.empty()) {
    PP t = Q.top();
    Q.pop();
    int cost = t.first.first;
    int y = t.first.second;
    int x = t.second.first;
    int bit = t.second.second;
    if (mp[y][x] == 'G' && bit == (1 << cnt) - 1)
      return cost;
    if (D[y][x][bit] < cost)
      continue;

    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      int nbit = bit;
      int ncost = cost + 4 - used[y][x];
      if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] == '#')
        continue;
      if (D[ny][nx][nbit] <= ncost)
        continue;
      if (mp[ny][nx] == 'M')
        nbit |= 1 << (M[P(ny, nx)]);
      Q.push(PP(P(ncost, ny), P(nx, nbit)));
      D[ny][nx][nbit] = ncost;
    }
  }
  assert(0);
}

int main() {

  cin >> w >> h;
  for (int i = 0; i < h; i++)
    cin >> mp[i];

  bfs();
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (mp[i][j] == 'S')
        cout << dijkstra(i, j) << endl;

  return 0;
}