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

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
const int INF = 100000000;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

bool in_range(int a, int b) { return a >= 0 && a < b; }

void bfs(map<int, int> &M, vector<int> &G, vector<string> C, int s) {
  int h = C.size(), w = C[0].length();
  queue<pair<int, int>> que;
  que.emplace(s, 0);
  while (!que.empty()) {
    int p = que.front().first, d = que.front().second;
    que.pop();
    if (M[p])
      G[M[p] - 1] = min(d, G[M[p] - 1]);
    for (int i = 0; i < 4; ++i) {
      int x = p / w + dx[i], y = p % w + dy[i], p_ = x * w + y;
      if (in_range(x, h) && in_range(y, w) && C[x][y] != 'x') {
        que.emplace(p_, d + 1);
        C[x][y] = 'x';
      }
    }
  }
}

vector<vector<int>> make_graph(vector<string> &C, vector<int> &D) {
  int h = C.size(), w = C[0].length(), n = D.size();
  map<int, int> M;
  for (int i = 0; i < n; ++i) {
    M[D[i]] = i + 1;
  }
  vector<vector<int>> G(n, vector<int>(n, INF));
  for (int i = 0; i < n; ++i) {
    bfs(M, G[i], C, D[i]);
  }
  return G;
}

int main() {
  int w, h;
  while (cin >> w >> h, w) {
    vector<string> C(h);
    vector<int> D;
    int s;
    for (int i = 0; i < h; ++i) {
      cin >> C[i];
      for (int j = 0; j < w; ++j) {
        if (C[i][j] == 'o')
          s = i * w + j;
        if (C[i][j] == '*') {
          D.push_back(i * w + j);
        }
      }
    }
    D.push_back(s);
    vector<vector<int>> G = make_graph(C, D);
    int n = G.size() - 1;
    vector<int> V(n);
    for (int i = 0; i < n; ++i)
      V[i] = i;
    int ans = INF;
    do {
      int t = 0, v = n;
      for (int i = 0; i < n; ++i) {
        t += G[v][V[i]];
        v = V[i];
      }
      ans = min(ans, t);
    } while (next_permutation(V.begin(), V.end()));
    if (ans >= INF)
      ans = -1;
    cout << ans << endl;
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
const int INF = 100000000;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

bool in_range(int a, int b) { return a >= 0 && a < b; }

void bfs(map<int, int> &M, vector<int> &G, vector<string> C, int s) {
  int h = C.size(), w = C[0].length();
  queue<pair<int, int>> que;
  que.emplace(s, 0);
  while (!que.empty()) {
    int p = que.front().first, d = que.front().second;
    que.pop();
    if (M[p])
      G[M[p] - 1] = min(d, G[M[p] - 1]);
    C[p / w][p % w] = 'x';
    for (int i = 0; i < 4; ++i) {
      int x = p / w + dx[i], y = p % w + dy[i], p_ = x * w + y;
      if (in_range(x, h) && in_range(y, w) && C[x][y] != 'x')
        que.emplace(p_, d + 1);
    }
  }
}

vector<vector<int>> make_graph(vector<string> &C, vector<int> &D) {
  int h = C.size(), w = C[0].length(), n = D.size();
  map<int, int> M;
  for (int i = 0; i < n; ++i) {
    M[D[i]] = i + 1;
  }
  vector<vector<int>> G(n, vector<int>(n, INF));
  for (int i = 0; i < n; ++i) {
    bfs(M, G[i], C, D[i]);
  }
  return G;
}

int main() {
  int w, h;
  while (cin >> w >> h, w) {
    vector<string> C(h);
    vector<int> D;
    int s;
    for (int i = 0; i < h; ++i) {
      cin >> C[i];
      for (int j = 0; j < w; ++j) {
        if (C[i][j] == 'o')
          s = i * w + j;
        if (C[i][j] == '*') {
          D.push_back(i * w + j);
        }
      }
    }
    D.push_back(s);
    vector<vector<int>> G = make_graph(C, D);
    int n = G.size() - 1;
    vector<int> V(n);
    for (int i = 0; i < n; ++i)
      V[i] = i;
    int ans = INF;
    do {
      int t = 0, v = n;
      for (int i = 0; i < n; ++i) {
        t += G[v][V[i]];
        v = V[i];
      }
      ans = min(ans, t);
    } while (next_permutation(V.begin(), V.end()));
    if (ans >= INF)
      ans = -1;
    cout << ans << endl;
  }
  return 0;
}