Problem p00721 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
int w, h;
vector<string> field;
int dist(pair<int, int> a, pair<int, int> b) {
  queue<pair<pair<int, int>, int>> bfs;
  set<pair<int, int>> already;
  bfs.push(make_pair(a, 0));
  while (!bfs.empty()) {
    pair<int, int> pos;
    int cost;
    tie(pos, cost) = bfs.front();
    bfs.pop();
    int y, x;
    tie(y, x) = pos;
    if (y < 0 || h <= y || x < 0 || w <= h)
      continue;
    if (field[y][x] == 'x')
      continue;
    if (!already.insert(pos).second)
      continue;
    if (pos == b)
      return cost;
    int dy[4] = {0, 0, -1, 1}, dx[4] = {-1, 1, 0, 0};
    for (int i = 0; i < 4; ++i)
      bfs.push(make_pair(make_pair(y + dy[i], x + dx[i]), cost + 1));
  }
  return 1048576;
}
int solve() {
  cin >> w >> h;
  if (!w && !h)
    return 0;
  field.resize(h);
  for (int i = 0; i < h; ++i)
    cin >> field[i];
  pair<int, int> robot;
  vector<pair<int, int>> dirty;
  for (int i = 0; i < h; ++i)
    for (int j = 0; j < w; ++j) {
      if (field[i][j] == 'o')
        robot = make_pair(i, j);
      if (field[i][j] == '*')
        dirty.push_back(make_pair(i, j));
    }
  // init bitdp[state][lastpos]
  vector<vector<int>> bitdp;
  bitdp.assign(1 << dirty.size(), vector<int>());
  for (int i = 0; i < (1 << dirty.size()); ++i)
    bitdp[i].assign(dirty.size(), 1048576);
  for (int i = 0; i < dirty.size(); ++i) {
    bitdp[1 << i][i] = dist(robot, dirty[i]);
    if (bitdp[1 << i][i] > 8192)
      return -1;
  }
  vector<vector<int>> ecost;
  ecost.assign(dirty.size(), vector<int>());
  for (int i = 0; i < dirty.size(); ++i)
    ecost[i].assign(dirty.size(), 1048576);
  for (int i = 0; i < dirty.size(); ++i)
    for (int j = 0; j < dirty.size(); ++j)
      ecost[i][j] = dist(dirty[i], dirty[j]);
  for (int i = 0; i < (1 << dirty.size()); ++i)
    for (int j = 0; j < dirty.size(); ++j) {
      if (i & (1 << j))
        continue;
      for (int k = 0; k < dirty.size(); ++k)
        if (i & (1 << k))
          bitdp[i | (1 << j)][j] =
              min(bitdp[i | (1 << j)][j], bitdp[i][k] + ecost[k][j]);
    }
  int answer = 1048576;
  for (int i = 0; i < dirty.size(); ++i)
    answer = min(answer, bitdp[(1 << dirty.size()) - 1][i]);
  if (answer > 65536)
    answer = -1;
  return answer;
}
int main() {
  for (;;) {
    int answer = solve();
    if (answer)
      cout << answer << endl;
    else
      break;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
int w, h;
vector<string> field;
int dist(pair<int, int> a, pair<int, int> b) {
  queue<pair<pair<int, int>, int>> bfs;
  set<pair<int, int>> already;
  bfs.push(make_pair(a, 0));
  while (!bfs.empty()) {
    pair<int, int> pos;
    int cost;
    tie(pos, cost) = bfs.front();
    bfs.pop();
    int y, x;
    tie(y, x) = pos;
    if (y < 0 || h <= y || x < 0 || w <= x)
      continue;
    if (field[y][x] == 'x')
      continue;
    if (!already.insert(pos).second)
      continue;
    if (pos == b)
      return cost;
    int dy[4] = {0, 0, -1, 1}, dx[4] = {-1, 1, 0, 0};
    for (int i = 0; i < 4; ++i)
      bfs.push(make_pair(make_pair(y + dy[i], x + dx[i]), cost + 1));
  }
  return 1048576;
}
int solve() {
  cin >> w >> h;
  if (!w && !h)
    return 0;
  field.resize(h);
  for (int i = 0; i < h; ++i)
    cin >> field[i];
  pair<int, int> robot;
  vector<pair<int, int>> dirty;
  for (int i = 0; i < h; ++i)
    for (int j = 0; j < w; ++j) {
      if (field[i][j] == 'o')
        robot = make_pair(i, j);
      if (field[i][j] == '*')
        dirty.push_back(make_pair(i, j));
    }
  // init bitdp[state][lastpos]
  vector<vector<int>> bitdp;
  bitdp.assign(1 << dirty.size(), vector<int>());
  for (int i = 0; i < (1 << dirty.size()); ++i)
    bitdp[i].assign(dirty.size(), 1048576);
  for (int i = 0; i < dirty.size(); ++i) {
    bitdp[1 << i][i] = dist(robot, dirty[i]);
    if (bitdp[1 << i][i] > 8192)
      return -1;
  }
  vector<vector<int>> ecost;
  ecost.assign(dirty.size(), vector<int>());
  for (int i = 0; i < dirty.size(); ++i)
    ecost[i].assign(dirty.size(), 1048576);
  for (int i = 0; i < dirty.size(); ++i)
    for (int j = 0; j < dirty.size(); ++j)
      ecost[i][j] = dist(dirty[i], dirty[j]);
  for (int i = 0; i < (1 << dirty.size()); ++i)
    for (int j = 0; j < dirty.size(); ++j) {
      if (i & (1 << j))
        continue;
      for (int k = 0; k < dirty.size(); ++k)
        if (i & (1 << k))
          bitdp[i | (1 << j)][j] =
              min(bitdp[i | (1 << j)][j], bitdp[i][k] + ecost[k][j]);
    }
  int answer = 1048576;
  for (int i = 0; i < dirty.size(); ++i)
    answer = min(answer, bitdp[(1 << dirty.size()) - 1][i]);
  if (answer > 65536)
    answer = -1;
  return answer;
}
int main() {
  for (;;) {
    int answer = solve();
    if (answer)
      cout << answer << endl;
    else
      break;
  }
  return 0;
}