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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 20;

/* typedef */

template <typename T> struct Pt {
  T x, y;

  Pt() {}
  Pt(T _x, T _y) : x(_x), y(_y) {}
  Pt(const Pt &pt) : x(pt.x), y(pt.y) {}

  Pt operator+(const Pt pt) const { return Pt(x + pt.x, y + pt.y); }
  Pt operator-() const { return Pt(-x, -y); }
  Pt operator-(const Pt pt) const { return Pt(x - pt.x, y - pt.y); }
  Pt operator*(T t) const { return Pt(x * t, y * t); }
  Pt operator/(T t) const { return Pt(x / t, y / t); }
  T dot(Pt v) { return x * v.x + y * v.y; }
  T cross(Pt v) { return x * v.y - y * v.x; }
  Pt mid(const Pt pt) { return Pt((x + pt.x) / 2, (y + pt.y) / 2); }
  T d2() { return x * x + y * y; }
  double d() { return sqrt(d2()); }

  Pt rot(double th) {
    double c = cos(th), s = sin(th);
    return Pt(c * x - s * y, s * x + c * y);
  }

  bool operator<(const Pt &pt) const {
    return x < pt.x || (x == pt.x && y < pt.y);
  }

  void print(string format) {
    printf(("(" + format + ", " + format + ")\\n").c_str(), x, y);
  }
};

typedef Pt<double> pt;

/* global variables */

int n;
pt hpt, dpt;
pt pts[MAX_N + 1];
bool used[MAX_N + 1];
double ddists[MAX_N + 1], pdists[MAX_N + 1][MAX_N + 1];

/* subroutines */

bool rec(int k, int i, double t) {
  // printf("rec(%d, %d, %f\\n", k, i, t);
  if (t >= ddists[i])
    return false;
  if (k >= n)
    return true;

  for (int j = 0; j <= n; j++)
    if (!used[j] && t + pdists[i][j] >= ddists[j])
      return false;

  for (int j = 0; j <= n; j++)
    if (!used[j]) {
      used[j] = true;
      if (rec(k + 1, j, t + pdists[i][j]))
        return true;
      used[j] = false;
    }

  return false;
}

/* main */

int main() {
  for (;;) {
    cin >> n >> hpt.x >> hpt.y >> dpt.x >> dpt.y;
    if (n == 0)
      break;

    pts[0] = hpt;
    for (int i = 1; i <= n; i++)
      cin >> pts[i].x >> pts[i].y;

    for (int i = 0; i <= n; i++) {
      ddists[i] = (pts[i] - dpt).d();
      pdists[i][i] = 0.0;
      for (int j = i + 1; j <= n; j++)
        pdists[i][j] = pdists[j][i] = (pts[i] - pts[j]).d();
    }

    memset(used, false, sizeof(used));
    used[0] = true;

    int tf = rec(0, 0, 0.0);
    cout << (tf ? "YES" : "NO") << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 20;

/* typedef */

template <typename T> struct Pt {
  T x, y;

  Pt() {}
  Pt(T _x, T _y) : x(_x), y(_y) {}
  Pt(const Pt &pt) : x(pt.x), y(pt.y) {}

  Pt operator+(const Pt pt) const { return Pt(x + pt.x, y + pt.y); }
  Pt operator-() const { return Pt(-x, -y); }
  Pt operator-(const Pt pt) const { return Pt(x - pt.x, y - pt.y); }
  Pt operator*(T t) const { return Pt(x * t, y * t); }
  Pt operator/(T t) const { return Pt(x / t, y / t); }
  T dot(Pt v) { return x * v.x + y * v.y; }
  T cross(Pt v) { return x * v.y - y * v.x; }
  Pt mid(const Pt pt) { return Pt((x + pt.x) / 2, (y + pt.y) / 2); }
  T d2() { return x * x + y * y; }
  double d() { return sqrt(d2()); }

  Pt rot(double th) {
    double c = cos(th), s = sin(th);
    return Pt(c * x - s * y, s * x + c * y);
  }

  bool operator<(const Pt &pt) const {
    return x < pt.x || (x == pt.x && y < pt.y);
  }

  void print(string format) {
    printf(("(" + format + ", " + format + ")\\n").c_str(), x, y);
  }
};

typedef Pt<double> pt;

/* global variables */

int n;
pt hpt, dpt;
pt pts[MAX_N + 1];
bool used[MAX_N + 1];
double ddists[MAX_N + 1], pdists[MAX_N + 1][MAX_N + 1];

/* subroutines */

bool rec(int k, int i, double t) {
  // printf("rec(%d, %d, %f\\n", k, i, t);
  if (k == n)
    return true;

  for (int j = 1; j <= n; j++)
    if (!used[j]) {
      double t0 = t + pdists[i][j];
      if (t0 < ddists[j]) {
        used[j] = true;
        if (rec(k + 1, j, t0))
          return true;
        used[j] = false;
      }
    }

  return false;
}

/* main */

int main() {
  for (;;) {
    cin >> n >> hpt.x >> hpt.y >> dpt.x >> dpt.y;
    if (n == 0)
      break;

    pts[0] = hpt;
    for (int i = 1; i <= n; i++)
      cin >> pts[i].x >> pts[i].y;

    for (int i = 0; i <= n; i++) {
      ddists[i] = (pts[i] - dpt).d();
      pdists[i][i] = 0.0;
      for (int j = i + 1; j <= n; j++)
        pdists[i][j] = pdists[j][i] = (pts[i] - pts[j]).d();
    }

    memset(used, false, sizeof(used));
    used[0] = true;

    int tf = rec(0, 0, 0.0);
    cout << (tf ? "YES" : "NO") << endl;
  }

  return 0;
}