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

#include <bits/stdc++.h>
#define N 21
using namespace std;
typedef pair<int, int> P;
int w, h, G[N][N];
string mp[N];
map<P, int> M;

void bfs(P s) {
  int D[N][N];
  memset(D, -1, sizeof(D));
  queue<P> Q;
  Q.push(s);
  int x = s.first, y = s.second;
  D[y][x] = 0;
  while (!Q.empty()) {
    P t = Q.front();
    Q.pop();
    x = t.first, y = t.second;
    if (mp[y][x] == '*' || mp[y][x] == 'o')
      G[M[s]][M[t]] = D[y][x];

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

int n, num[11];
P start;
int calc() {
  if (M[start] != num[0])
    return 1e9;
  int res = 0;
  for (int i = 1; i < n; i++)
    res += G[num[i - 1]][num[i]];
  return res;
}

int dfs(int idx) {
  if (idx == n)
    return calc();
  int res = 1e9;
  for (int i = 0; i < n; i++) {
    if (num[i] != -1)
      continue;
    num[i] = idx;
    res = min(res, dfs(idx + 1));
    num[i] = -1;
  }
  return res;
}

int main() {
  while (1) {
    cin >> w >> h;
    if (!w && !h)
      break;
    for (int i = 0; i < h; i++)
      cin >> mp[i];
    M.clear();
    memset(G, -1, sizeof(G));
    memset(num, -1, sizeof(num));
    n = 0;
    vector<P> p;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        P t = P(j, i);
        if (mp[i][j] == '*' || mp[i][j] == 'o')
          p.push_back(t), M[t] = n++;
        if (mp[i][j] == 'o')
          start = t;
      }
    for (int i = 0; i < n; i++)
      bfs(p[i]);

    bool flg = 1;
    for (int i = 0; i < n; i++)
      if (G[0][i] == -1)
        flg = 0;
    cout << (flg ? dfs(0) : -1) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define N 21
using namespace std;
typedef pair<int, int> P;
int w, h;
string mp[N];
int G[N][N];
map<P, int> M;

void bfs(P start) {
  int D[N][N];
  memset(D, -1, sizeof(D));
  queue<P> Q;
  Q.push(start);
  int x = start.first, y = start.second;
  D[y][x] = 0;
  while (!Q.empty()) {
    P t = Q.front();
    Q.pop();
    x = t.first, y = t.second;

    if (mp[y][x] == '*' || mp[y][x] == 'o')
      G[M[start]][M[t]] = D[y][x];

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

vector<P> p;
P start;
int n, num[11];

int calc() {
  int res = 0;
  for (int i = 1; i < n; i++)
    res += G[num[i - 1]][num[i]];
  return res;
}

int dfs(int idx) {
  if (idx == n)
    return calc();
  int res = 1e9;
  for (int i = 1; i < n; i++) {
    if (num[i] >= 0)
      continue;
    num[i] = idx;
    res = min(res, dfs(idx + 1));
    num[i] = -1;
  }
  return res;
}

int main() {
  while (1) {
    cin >> w >> h;
    for (int i = 0; i < h; i++)
      cin >> mp[i];
    M.clear();
    p.clear();
    memset(G, -1, sizeof(G));
    memset(num, -1, sizeof(num));
    n = 0;

    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        P t = P(j, i);
        if (mp[i][j] == '*' || mp[i][j] == 'o')
          p.push_back(t), M[t] = n++;
        if (mp[i][j] == 'o')
          start = t;
      }
    for (int i = 0; i < n; i++)
      bfs(p[i]);
    int flg = 1;
    for (int i = 0; i < n; i++)
      if (G[0][i] == -1)
        flg = 0;
    num[0] = M[start];
    cout << (flg ? dfs(1) : -1) << endl;
  }
  return 0;
}