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

#include <iostream>
#include <queue>
#include <string.h>
#include <vector>
#define f first
#define s second
#define inf 100000001
using namespace std;

int w, h, d[20][20], ii, sum, map[20][20], a, dp[1 << 12][20];
int x[4] = {1, -1, 0, 0};
int y[4] = {0, 0, 1, -1};
char c[20][20];
vector<pair<int, int>> v;
pair<int, int> u;
queue<pair<int, int>> q;

bool in(int a, int b) {
  if (a < 0 || b < 0 || a >= h || b >= w)
    return false;
  return true;
}
/*
void solve()
{
  for(int S=0;S<1<<a;S++){
    fill(dp[S],dp[S]+a,inf);
  }
  dp[(1<<a)-1][0]=0;

  for(int S=(1<<a)-2;S>=0;S--){
    for(int v=0;v<a;v++){
      for(int u=0;u<a;u++){
        if(!(S>>u & 1)){
          dp[S][v]=min(dp[S][v],dp[S|1<<u][u]+map[v][u]);
        }
      }
    }
  }
  int ans=inf;
  for(int i=1;i<a;i++)ans=min(ans,dp[0][i]);
  if(ans>=inf)cout<<-1<<endl;
  cout<<ans<<endl;
}
*/

int rec(int S, int v) {
  if (dp[S][v] >= 0) {
    return dp[S][v];
  }
  if (S == (1 << a) - 1 && v == 0) {
    return dp[S][v] = 0;
  }
  int res = inf;
  for (int i = 0; i < a; i++) {
    if (!(S >> i & 1)) {
      res = min(res, rec(S | 1 << i, i) + map[v][i]);
    }
  }
  return dp[S][v] = res;
}

int main() {
  while (1) {
    cin >> w >> h;
    if (w == 0 && h == 0)
      break;
    v.clear();
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> c[i][j];
        if (c[i][j] == 'o')
          v.push_back(make_pair(i, j));
      }
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (c[i][j] == '*')
          v.push_back(make_pair(i, j));
      }
    }
    for (int i = 0; i < 20; i++) {
      for (int j = 0; j < 20; j++)
        map[i][j] = 0;
    }
    for (int k = 0; k < v.size(); k++) {
      q.push(make_pair(v[k].f, v[k].s));
      for (int i = 0; i < 20; i++) {
        for (int j = 0; j < 20; j++)
          d[i][j] = inf;
      }
      d[v[k].f][v[k].s] = 0;
      while (!q.empty()) {
        u = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
          int xx = u.f + x[i], yy = u.s + y[i];
          if (in(xx, yy)) {
            if (d[xx][yy] != inf)
              continue;
            if (c[xx][yy] != 'x') {
              q.push(make_pair(xx, yy));
              d[xx][yy] = d[u.f][u.s] + 1;
            }
          }
        }
      }
      for (int i = 0; i < v.size(); i++)
        map[k][i] = d[v[i].f][v[i].s];
    }
    a = v.size();
    memset(dp, -1, sizeof(dp));
    int ans = inf;
    for (int i = 1; i < a; i++) {
      ans = min(ans, rec(0, i));
    }
    if (ans >= inf)
      cout << -1 << endl;
    else
      cout << ans << endl;
    // solve();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int main() {
  int w, h, d[20][20], ii, min, sum, color[20][20], x, y;
  int xy[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
  char c[20][20];
  vector<pair<int, int>> v;
  pair<int, int> u;
  queue<pair<int, int>> q;
  while (1) {
    cin >> w >> h;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> c[i][j];
        if (c[i][j] == 'o') {
          x = i;
          y = j;
        }
        if (c[i][j] == '*') {
          v.push_back(make_pair(i, j));
        }
      }
    }
    sum = 0;
    while (1) {
      c[x][y] = '.';
      // cout<<x<<y;
      q.push(make_pair(x, y));
      for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++)
          d[i][j] = 500;
      }
      d[x][y] = 0;
      while (!q.empty()) {
        u = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
          if (d[u.first + xy[i][0]][u.second + xy[i][1]] != 500)
            continue;
          if (c[u.first + xy[i][0]][u.second + xy[i][1]] != 'x') {
            q.push(make_pair(u.first + xy[i][0], u.second + xy[i][1]));
            d[u.first + xy[i][0]][u.second + xy[i][1]] =
                d[u.first][u.second] + 1;
          }
        }
      }
      min = 500;
      for (int i = 0; i < v.size(); i++) {
        if (min > d[v[i].first][v[i].second]) {
          min = d[v[i].first][v[i].second];
          x = v[i].first;
          y = v[i].second;
          ii = i;
        }
      }
      if (min == 500)
        break;
      sum += min;
      v.erase(v.begin() + ii);
      if (v.empty())
        break;
    }
    if (min == 500)
      cout << "-1" << endl;
    else
      cout << sum << endl;
  }
  return 0;
}