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

#include "bits/stdc++.h"
using namespace std;
typedef pair<int, int> P;
char tile[20][21];
bool vis[20][20];
int d[20][20];
int dist[11][11];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int w, h;
void calc(int sx, int sy) {
  memset(vis, 0, sizeof(vis));
  memset(d, -1, sizeof(d));
  vis[sy][sx] = 1;
  d[sy][sx] = 0;
  queue<P> Q;
  Q.push(P(sx, sy));
  while (!Q.empty()) {
    P p = Q.front();
    Q.pop();
    int x = p.first, y = p.second;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      if (nx < 0 || nx >= w || ny < 0 || ny >= h || tile[ny][nx] == 'x' ||
          vis[ny][nx])
        continue;
      vis[ny][nx] = 1;
      d[ny][nx] = d[y][x] + 1;
      Q.push(P(nx, ny));
    }
  }
}
int main() {
  while (cin >> w >> h, w) {
    int sx, sy;
    vector<P> dirty;
    for (int i = 0; i < h; i++) {
      cin >> tile[i];
      for (int j = 0; j < w; j++)
        if (tile[i][j] == 'o')
          sx = j, sy = i;
    }
    dirty.emplace_back(sx, sy);
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++)
        if (tile[i][j] == '*')
          dirty.emplace_back(j, i);
    }
    for (int i = 0; i < dirty.size(); i++) {
      calc(dirty[i].first, dirty[i].second);
      for (int j = 0; j < dirty.size(); j++) {
        dist[i][j] = d[dirty[j].second][dirty[j].first];
      }
    }
    int perm[11];
    for (int i = 0; i < dirty.size(); i++)
      perm[i] = i;
    int ans = 1 << 30;
    do {
      int sum = 0;
      int prev = 0;
      bool ok = 1;
      for (int i = 1; i < dirty.size(); i++) {
        int t = dist[prev][perm[i]];
        if (t == -1) {
          ok = 0;
          break;
        }
        sum += t;
        prev = perm[i];
      }
      if (!ok)
        continue;
      ans = min(ans, sum);
    } while (next_permutation(perm + 1, perm + dirty.size()));
    if (ans == 1 << 30)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}


Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
typedef pair<int, int> P;
char tile[20][21];
bool vis[20][21];
int d[20][21];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int w, h;
int dist(int sx, int sy, int gx, int gy) {
  memset(vis, 0, sizeof(vis));
  memset(d, -1, sizeof(d));
  vis[sy][sx] = 1;
  d[sy][sx] = 0;
  queue<P> Q;
  Q.push(P(sx, sy));
  while (!Q.empty()) {
    P p = Q.front();
    Q.pop();
    int x = p.first, y = p.second;
    if (x == gx && y == gy)
      return d[gy][gx];
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      if (nx < 0 || nx >= w || ny < 0 || ny >= h || tile[ny][nx] == 'x' ||
          vis[ny][nx])
        continue;
      vis[ny][nx] = 1;
      d[ny][nx] = d[y][x] + 1;
      Q.push(P(nx, ny));
    }
  }
  return -1;
}
int main() {
  while (cin >> w >> h, w) {
    int sx, sy;
    vector<P> dirty;
    for (int i = 0; i < h; i++) {
      cin >> tile[i];
      for (int j = 0; j < w; j++) {
        if (tile[i][j] == 'o')
          sx = j, sy = i;
        else if (tile[i][j] == '*')
          dirty.emplace_back(j, i);
      }
    }
    int perm[10];
    for (int i = 0; i < dirty.size(); i++)
      perm[i] = i;
    int ans = 1 << 30;
    do {
      int sum = 0;
      int x = sx, y = sy;
      bool ok = 1;
      for (int i = 0; i < dirty.size(); i++) {
        int t = dist(x, y, dirty[perm[i]].first, dirty[perm[i]].second);
        if (t == -1) {
          ok = 0;
          break;
        }
        sum += t;
        x = dirty[perm[i]].first;
        y = dirty[perm[i]].second;
      }
      if (!ok)
        continue;
      ans = min(ans, sum);
    } while (next_permutation(perm, perm + dirty.size()));
    if (ans == 1 << 30)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}