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

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define MAX 21
#define EPS 1e-9
#define INF 1e9

struct Point {
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}
};

int N;
Point h, d, crystal[MAX];

double dist(Point a, Point b) {
  return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

bool ok;

void rec(int S, int v, double total_dist) {
  if (ok)
    return;

  if (S == (1 << N) - 1) {
    ok = true;
    return;
  }
  for (int u = 0; u < N; u++) {
    if (!(S >> u & 1)) {
      if (total_dist + dist(crystal[v], crystal[u]) >= dist(d, crystal[u])) {
        return;
      }
    }
  }
  for (int u = 0; u < N; u++) {
    if (!(S >> u & 1) && !ok) {
      rec(S | 1 << u, u, total_dist + dist(crystal[v], crystal[u]));
    }
  }
}

bool solve() {
  for (int i = 0; i < N; i++) {
    ok = false;
    rec(0, i, dist(h, crystal[i]));
    if (ok) {
      return true;
    }
  }

  return false;
}

int main() {
  while (cin >> N >> h.x >> h.y >> d.x >> d.y, (N + h.x + h.y + d.x + d.y)) {
    for (int i = 0; i < N; i++) {
      cin >> crystal[i].x >> crystal[i].y;
    }
    cout << (solve() ? "YES" : "NO") << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define MAX 21
#define EPS 1e-9
#define INF 1e9

struct Point {
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}

  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }

  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }

  Point operator*(const double &k) const { return Point(x * k, y * k); }

  Point operator/(const double &k) const { return Point(x / k, y / k); }

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }

  double norm() { return x * x + y * y; }
  double dot(const Point &p) const { return x * p.x + y * p.y; }
  double Abs() { return sqrt(norm()); }
};

typedef Point Vector;

struct Segment {
  Vector s, t;

  Segment() {}
  Segment(Vector s, Vector t) : s(s), t(t) {}

  Point Projection(Point &p) {
    Vector base = t - s;
    double t = (p - s).dot(base) / base.norm();
    return s + base * t;
  }
  Point Reflection(Point &p) { return p + (Projection(p) - p) * 2.0; }

  bool intersectSP(Point &p) {
    return (((s - p).Abs() + (t - p).Abs() - (t - s).Abs()) < EPS);
  }

  double distanceSP(Point &p) {
    Point r = Projection(p);
    if (intersectSP(r))
      return (r - p).Abs();
    return min((s - p).Abs(), (t - p).Abs());
  }
};

int N;
Point h, d, crystal[MAX];

double dist(Point a, Point b) {
  return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

bool used[MAX], ok;

void rec(int S, int v, double total_dist) {
  if (ok)
    return;

  if (S == (1 << N) - 1) {
    ok = true;
    return;
  }
  for (int u = 0; u < N; u++) {
    Segment s = Segment(crystal[v], crystal[u]);
    if (s.distanceSP(d) < total_dist)
      return;
    if (total_dist + dist(crystal[v], crystal[u]) + EPS > dist(d, crystal[u])) {
      return;
    }
  }
  for (int u = 0; u < N; u++) {
    if (ok)
      return;
    if (!(S >> u & 1)) {
      rec(S | 1 << u, u, total_dist + dist(crystal[v], crystal[u]));
    }
  }
}

bool solve() {
  sort(crystal, crystal + N);

  ok = false;
  for (int i = 0; i < N; i++) {
    memset(used, false, sizeof(used));
    rec(0, i, dist(h, crystal[i]));
    if (ok) {
      return true;
    }
  }

  return false;
}

int main() {
  while (cin >> N >> h.x >> h.y >> d.x >> d.y, (N + h.x + h.y + d.x + d.y)) {
    for (int i = 0; i < N; i++) {
      cin >> crystal[i].x >> crystal[i].y;
    }
    cout << (solve() ? "YES" : "NO") << endl;
  }

  return 0;
}