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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define REP(i, a, n) for (i = a; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define foreach(it, x)                                                         \\
  for (typeof(x.begin()) it = x.begin(); it != x.end(); it++)

int n, hx, hy, dx, dy, cx[25], cy[25];
int ans;
const double inf = 999999999.9;
double dist[25][25], start[25], dead[25];
bool used[25];
double memo[1 << 20];

double sqr(int x) { return (double)x * x; }

void solve(int node, int cnt, double cost, int S) {
  int i, j;

  // printf("cost = %lf, dead[%d] = %lf\\n",cost ,node, dead[node]);
  if (cost >= dead[node] || memo[S] <= cost)
    return;

  ans = max(ans, cnt);
  memo[S] = cost;
  if (cnt == n)
    return;

  /*
    »Ýn©çÜ¾EÁÄ¢È¢NX^Ì¤¿AêÂÅàæêÈ¢Ìª éÈçOUT
   */
  rep(i, n) {
    if (!used[i]) {
      if (cost + dist[node][i] >= dead[i])
        return;
    }
  }

  // printf("cnt = %d, node = %d, cost = %lf\\n",cnt, node, cost);

  rep(i, n) {
    if (!used[i]) {
      used[i] = true;
      solve(i, cnt + 1, cost + dist[node][i], S | (1 << i));
      used[i] = false;
      if (ans == n)
        return;
    }
  }
}

int main() {
  int i, j;

  while (cin >> n >> hx >> hy >> dx >> dy, n | hx | hy | dx | dy) {
    // init
    ans = 0;
    rep(i, 25) rep(j, 25) dist[i][j] = inf;
    rep(i, 1 << n) memo[i] = inf;
    memset(used, false, sizeof(used));

    // input
    set<pair<int, int>> sc;
    rep(i, n) {
      int x, y;
      cin >> x >> y;
      sc.insert(make_pair(x, y));
    }

    j = 0;
    foreach (it, sc) {
      cx[j] = it->first, cy[j] = it->second;
      j++;
    }
    n = j;

    // start -> other crystal
    rep(i, n) start[i] = sqrt(sqr(hx - cx[i]) + sqr(hy - cy[i]));

    // dead line
    rep(i, n) dead[i] = sqrt(sqr(dx - cx[i]) + sqr(dy - cy[i]));

    // crystal -> crystal
    rep(i, n) {
      REP(j, i + 1, n) {
        double d = sqrt(sqr(cx[i] - cx[j]) + sqr(cy[i] - cy[j]));
        dist[i][j] = dist[j][i] = d;
      }
    }

    rep(i, n) {
      used[i] = true;
      solve(i, 1, start[i], 1 << i);
      used[i] = false;
    }

    puts(ans == n ? "YES" : "NO");
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define REP(i, a, n) for (int i = (a); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define DEB 0

/*
  dist[0]ÍEÒ
 */
int n, hx, hy, dx, dy;
int cx[32], cy[32];
double dist[32][32]; // [1][0]  1base and 0base
double maoo[32];
double inf = 999999999.0;

double sqr(int x) { return (double)x * x; }

bool solve(int now, int S, double cost) {
#if DEB
  printf("now:%d  S:%d  cost:%lf\\n", now, S, cost);
#endif

  if (S == ((1 << n) - 1))
    return true;
  rep(i, n) if (!((1 << i) & S)) {
#if DEB
    printf("i:%d  %lf < %lf\\n", i, cost + dist[now][i], maoo[i]);
#endif
    if (cost + dist[now][i] < maoo[i]) {
      if (solve(i + 1, S | (1 << i), cost + dist[now][i]))
        return true;
    }
  }
  return false;
}

int main() {
  while (cin >> n >> hx >> hy >> dx >> dy, n | hx | hy | dx | dy) {
    rep(i, 32) rep(j, 32) dist[i][j] = inf;
    set<pair<int, int>> si;
    vector<int> v;
    rep(i, n) {
      cin >> cx[i] >> cy[i];
      if (si.find(make_pair(cx[i], cy[i])) != si.end())
        continue;
      si.insert(make_pair(cx[i], cy[i]));
      v.push_back(i);
    }
    n = v.size();
    rep(i, n) {
      dist[0][i] = sqrt(sqr(hx - cx[v[i]]) + sqr(hy - cy[v[i]]));
      maoo[i] = sqrt(sqr(dx - cx[v[i]]) + sqr(dy - cy[v[i]]));
    }
    // eXÌNX^©çÊÌNX^ÖÌ£vZ
    REP(i, 1, n + 1) {
      REP(j, i + 1, n + 1) {
        dist[i][j - 1] = dist[j][i - 1] =
            sqrt(sqr(cx[i - 1] - cx[j - 1]) + sqr(cy[i - 1] - cy[j - 1]));
      }
    }
#if DEB
    rep(i, n + 1) {
      rep(j, n + 1) { printf("%9lf ", dist[i][j] == inf ? -1 : dist[i][j]); }
      puts("");
    }
#endif
    if (solve(0, 0, 0.0)) {
      puts("YES");
    } else {
      puts("NO");
    }
  }
  return 0;
}