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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> PP;
#define C first.first
#define F first.second
#define X second.first
#define Y second.second
#define INF (1 << 29)
int W, H;
char fie[101][101];
int mvc[101][101];
int dmx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dmy[] = {0, 1, 0, -1, 1, -1, -1, 1};
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int h[101][101][1 << 5];
int gx, gy;
int MC;
bool check(int x, int y) {
  if (x < 0 || y < 0 || x >= W || y >= H)
    return true;
  return false;
}
void printmv() {
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++)
      printf("%2d ", mvc[j][i]);
    puts("");
  }
}
void printh() {
  for (int k = 0; k < (1 << MC); k++)
    for (int i = 0; i < H; i++)
      for (int j = 0; j < W; j++)
        printf("h[%d][%d][%d]=%d\\n", j, i, k, h[j][i][k]);
}
int solve(int x, int y) {
  // printmv();
  queue<PP> q;
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      for (int k = 0; k < (1 << MC); k++)
        h[j][i][k] = INF;
  q.push(PP(P(0, 0), P(x, y)));
  h[x][y][0] = 0;
  while (!q.empty()) {
    PP p = q.front();
    q.pop();
    x = p.X;
    y = p.Y;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i], ny = y + dy[i];
      if (check(nx, ny))
        continue;
      if (fie[nx][ny] == '#')
        continue;
      if ('0' <= fie[nx][ny] && fie[nx][ny] <= '5') {
        int mc = fie[nx][ny] - '0';
        int st = (p.F | (1 << mc));
        if (h[nx][ny][st] > p.C + mvc[x][y]) {
          h[nx][ny][st] = p.C + mvc[x][y];
          q.push(PP(P(p.C + mvc[x][y], st), P(nx, ny)));
        }
      } else {
        if (h[nx][ny][p.F] > p.C + mvc[x][y]) {
          h[nx][ny][p.F] = p.C + mvc[x][y];
          q.push(PP(P(p.C + mvc[x][y], p.F), P(nx, ny)));
        }
      }
    }
  }
  //  printh();
  // cout << gx << " " << gy << " " << (1<<MC)-1 << " " <<
  // h[gx][gy][(1<<MC)-1]<<"\\n";
  return h[gx][gy][(1 << MC) - 1];
}
void mark(int x, int y, int c) {
  for (int i = 0; i < 8; i++) {
    int nx = x + dmx[i], ny = y + dmy[i];
    if (check(nx, ny))
      continue;
    mvc[nx][ny] = max(mvc[nx][ny], c);
  }
  if (c == 3) {
    for (int i = 0; i < 8; i++) {
      int nx = x + dmx[i], ny = y + dmy[i];
      if (check(nx, ny))
        continue;
      mark(nx, ny, c - 1);
    }
  }
}
int main() {
  int sx, sy;
  cin >> W >> H;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> fie[j][i];
      mvc[j][i] = 1;
    }
  }
  MC = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (fie[j][i] == '#') {
        mark(j, i, 3);
      } else if (fie[j][i] == 'S') {
        sx = j;
        sy = i;
      } else if (fie[j][i] == 'M') {
        fie[j][i] = '0' + MC;
        MC++;
      } else if (fie[j][i] == 'G') {
        gx = j;
        gy = i;
      }
    }
  }
  cout << solve(sx, sy) << "\\n";
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> PP;
#define C first.first
#define F first.second
#define X second.first
#define Y second.second
#define INF (1 << 29)
int W, H;
char fie[101][101];
int mvc[101][101];
int dmx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dmy[] = {0, 1, 0, -1, 1, -1, -1, 1};
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int h[101][101][1 << 5];
int gx, gy;
int MC;
bool check(int x, int y) {
  if (x < 0 || y < 0 || x >= W || y >= H)
    return true;
  return false;
}
void printmv() {
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++)
      printf("%2d ", mvc[j][i]);
    puts("");
  }
}
void printh() {
  for (int k = 0; k < (1 << MC); k++)
    for (int i = 0; i < H; i++)
      for (int j = 0; j < W; j++)
        printf("h[%d][%d][%d]=%d\\n", j, i, k, h[j][i][k]);
}
int solve(int x, int y) {
  // printmv();
  priority_queue<PP> q;
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      for (int k = 0; k < (1 << MC); k++)
        h[j][i][k] = INF;
  q.push(PP(P(0, 0), P(x, y)));
  h[x][y][0] = 0;
  while (!q.empty()) {
    PP p = q.top();
    q.pop();
    x = p.X;
    y = p.Y;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i], ny = y + dy[i];
      if (check(nx, ny))
        continue;
      if (fie[nx][ny] == '#')
        continue;
      if ('0' <= fie[nx][ny] && fie[nx][ny] <= '5') {
        int mc = fie[nx][ny] - '0';
        int st = (p.F | (1 << mc));
        if (h[nx][ny][st] > p.C + mvc[x][y]) {
          h[nx][ny][st] = p.C + mvc[x][y];
          q.push(PP(P(p.C + mvc[x][y], st), P(nx, ny)));
        }
      } else {
        if (h[nx][ny][p.F] > p.C + mvc[x][y]) {
          h[nx][ny][p.F] = p.C + mvc[x][y];
          q.push(PP(P(p.C + mvc[x][y], p.F), P(nx, ny)));
        }
      }
    }
  }
  //  printh();
  // cout << gx << " " << gy << " " << (1<<MC)-1 << " " <<
  // h[gx][gy][(1<<MC)-1]<<"\\n";
  return h[gx][gy][(1 << MC) - 1];
}
void mark(int x, int y, int c) {
  for (int i = 0; i < 8; i++) {
    int nx = x + dmx[i], ny = y + dmy[i];
    if (check(nx, ny))
      continue;
    mvc[nx][ny] = max(mvc[nx][ny], c);
  }
  if (c == 3) {
    for (int i = 0; i < 8; i++) {
      int nx = x + dmx[i], ny = y + dmy[i];
      if (check(nx, ny))
        continue;
      mark(nx, ny, c - 1);
    }
  }
}
int main() {
  int sx, sy;
  cin >> W >> H;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> fie[j][i];
      mvc[j][i] = 1;
    }
  }
  MC = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (fie[j][i] == '#') {
        mark(j, i, 3);
      } else if (fie[j][i] == 'S') {
        sx = j;
        sy = i;
      } else if (fie[j][i] == 'M') {
        fie[j][i] = '0' + MC;
        MC++;
      } else if (fie[j][i] == 'G') {
        gx = j;
        gy = i;
      }
    }
  }
  cout << solve(sx, sy) << "\\n";
}