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

#include <float.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <math.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;

typedef double R;

template <class T> class _Point {
public:
  T x;
  T y;
  _Point() {}
  _Point(T _x, T _y) : x(_x), y(_y) {}
  _Point(const _Point &v) : x(v.x), y(v.y) {}

  inline const _Point operator+(const _Point &v) {
    return _Point(x + v.x, y + v.y);
  }
  inline const _Point operator-(const _Point &v) {
    return _Point(x - v.x, y - v.y);
  }
  inline T abs() const { return sqrt(x * x + y * y); }
  inline _Point unit() const {
    T len = abs();
    return _Point(x / len, y / len);
  }
  inline T operator*(const _Point &v) const { return x * v.x + y * v.y; }
  inline const _Point operator*(const T &len) const {
    return _Point(len * x, len * y);
  }
  inline bool operator==(const _Point &p) const {
    return (x == p.x) && (y == p.y);
  }
  inline R distance(const _Point &t) const {
    return sqrt((x - t.x) * (x - t.x) + (y - t.y) * (y - t.y));
  }
  inline bool operator<(const _Point &p) const { return 0; }
};

typedef _Point<R> Point;
typedef Point Vector;

class SegmentLine {
public:
  Point start, end;
  inline R distance() const { return start.distance(end); }
  inline SegmentLine(const Point &_s, const Point &_e) : start(_s), end(_e) {}
  inline SegmentLine() {}

  //????????¨???????????¢
  R distance(const Point &t) const {
    Vector dir = end;
    dir = dir - start;
    if (dir.abs() < DBL_EPSILON * 16) {
      return t.distance(start);
    }

    Vector e = dir.unit();
    Vector v = t;
    v = v - start;
    R inner = v * e;
    if (inner <= 0) {
      return start.distance(t);
    } else if (inner > distance()) {
      return end.distance(t);
    } else {
      double d = v.abs();
      return sqrt(d * d - inner * inner);
    }
  }
};

typedef pair<int, Point> indexedPoint;

class Esa : public indexedPoint {
public:
  R distanceToKyoten;
};

class Kyoten {
  list<indexedPoint> _points;
  list<SegmentLine> _lines;

public:
  R totallength() {
    R length = 0;
    for (list<SegmentLine>::iterator it = _lines.begin(); it != _lines.end();
         ++it) {
      length += it->distance();
    }
    return length;
  }

  void init(int index, const Point &p0) {
    _points.push_back(indexedPoint(index, p0));
  }
  void add(int index, const Point &p, SegmentLine &sl) {
    R mindistance = -1;
    Point near;
    for (list<indexedPoint>::iterator it = _points.begin(); it != _points.end();
         ++it) {
      Point &itp = it->second;
      R distance = itp.distance(p);
      if (mindistance < 0 || distance < (mindistance - DBL_EPSILON * 16)) {
        mindistance = distance;
        near = itp;
      }
    }
    _points.push_back(indexedPoint(index, p));
    _points.sort();
    if (mindistance >= 0) {
      sl = SegmentLine(near, p);
      _lines.push_back(sl);
    }
  }
};

int main() {
  std::istream &c_in = cin;

  int N, M, X, Y;
  c_in >> N >> M >> X >> Y;
  Point p0(X, Y);
  Kyoten kyoten;
  kyoten.init(0, p0);

  list<Esa> P;
  for (int i = 0; i < N; ++i) {
    Point p;
    c_in >> p.x >> p.y;
    Esa esa;
    esa.first = i + 1;
    esa.second = p;
    esa.distanceToKyoten = p0.distance(p);
    P.push_back(esa);
  }

  int esa = 0;
  while (esa < M) {
    SegmentLine sl;
    {
      R dist = -1;
      list<Esa>::iterator nearby;
      for (list<Esa>::iterator it = P.begin(); it != P.end(); ++it) {
        if ((dist < 0) || (it->distanceToKyoten < (dist - DBL_EPSILON * 16))) {
          dist = it->distanceToKyoten;
          nearby = it;
        }
      }
      kyoten.add(nearby->first, nearby->second, sl);
      P.erase(nearby);
    }

    {
      // update distanceToKyoten
      for (list<Esa>::iterator it = P.begin(); it != P.end(); ++it) {
        R dist = sl.distance(it->second);
        if (dist < (it->distanceToKyoten - DBL_EPSILON * 16)) {
          it->distanceToKyoten = dist;
        }
      }
    }

    esa++;
  }
  //
  cout << fixed << setprecision(10) << kyoten.totallength() << endl;
}

Error: TLE

Fixed submission:

#include <float.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <math.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;

typedef double R;

template <class T> class _Point {
public:
  T x;
  T y;
  _Point() {}
  _Point(T _x, T _y) : x(_x), y(_y) {}
  _Point(const _Point &v) : x(v.x), y(v.y) {}

  inline const _Point operator+(const _Point &v) {
    return _Point(x + v.x, y + v.y);
  }
  inline const _Point operator-(const _Point &v) {
    return _Point(x - v.x, y - v.y);
  }
  inline T abs() const { return sqrt(x * x + y * y); }
  inline _Point unit() const {
    T len = abs();
    return _Point(x / len, y / len);
  }
  inline T operator*(const _Point &v) const { return x * v.x + y * v.y; }
  inline const _Point operator*(const T &len) const {
    return _Point(len * x, len * y);
  }
  inline bool operator==(const _Point &p) const {
    return (x == p.x) && (y == p.y);
  }
  inline R distance(const _Point &t) const {
    return sqrt((x - t.x) * (x - t.x) + (y - t.y) * (y - t.y));
  }
  inline bool operator<(const _Point &p) const { return 0; }
};

typedef _Point<R> Point;
typedef Point Vector;

class SegmentLine {
public:
  Point start, end;
  inline R distance() const { return start.distance(end); }
  inline SegmentLine(const Point &_s, const Point &_e) : start(_s), end(_e) {}

  //????????¨???????????¢
  R distance(const Point &t) const {
    Vector dir = end;
    dir = dir - start;
    if (dir.abs() < DBL_EPSILON * 16) {
      return t.distance(start);
    }

    Vector e = dir.unit();
    Vector v = t;
    v = v - start;
    R inner = v * e;
    if (inner <= 0) {
      return start.distance(t);
    } else if (inner > distance()) {
      return end.distance(t);
    } else {
      double d = v.abs();
      return sqrt(d * d - inner * inner);
    }
  }
};

typedef pair<int, Point> indexedPoint;
class Kyoten {
  list<indexedPoint> _points;
  list<SegmentLine> _lines;

public:
  R totallength() {
    R length = 0;
    for (list<SegmentLine>::iterator it = _lines.begin(); it != _lines.end();
         ++it) {
      length += it->distance();
    }
    return length;
  }
  // p ??¨????????¢?????????
  R distance(const Point p) {
    R mindist = -1;
    for (list<SegmentLine>::iterator it = _lines.begin(); it != _lines.end();
         ++it) {
      R dist = it->distance(p);
      if (mindist < 0 || dist < (mindist - DBL_EPSILON * 16)) {
        mindist = dist;
      }
    }
    if (mindist < 0) {
      for (list<indexedPoint>::iterator it = _points.begin();
           it != _points.end(); ++it) {
        R dist = it->second.distance(p);
        if (mindist < 0 || dist < (mindist - DBL_EPSILON * 16)) {
          mindist = dist;
        }
        break;
      }
    }
    return mindist;
  }
  void add(int index, const Point &p) {
    R mindistance = -1;
    Point near;
    for (list<indexedPoint>::iterator it = _points.begin(); it != _points.end();
         ++it) {
      Point &itp = it->second;
      // if (itp == p){
      //	return;
      // }
      R distance = itp.distance(p);
      if (mindistance < 0 || distance < (mindistance - DBL_EPSILON * 16)) {
        mindistance = distance;
        near = itp;
      }
    }
    _points.push_back(indexedPoint(index, p));
    _points.sort();
    if (mindistance >= 0) {
      _lines.push_back(SegmentLine(near, p));
    }
  }
};

int main() {
  std::istream &c_in = cin;

  int N, M, X, Y;
  c_in >> N >> M >> X >> Y;

  Kyoten kyoten;
  kyoten.add(0, Point(X, Y));

  list<indexedPoint> P;
  for (int i = 0; i < N; ++i) {
    Point p;
    c_in >> p.x >> p.y;
    P.push_back(indexedPoint(i + 1, p));
  }

  int esa = 0;
  while (esa < M) {
    R dist;
    list<indexedPoint>::iterator nearby = P.end();
    for (list<indexedPoint>::iterator it = P.begin(); it != P.end(); ++it) {
      R d = kyoten.distance(it->second);
      if ((nearby == P.end()) || d < (dist - DBL_EPSILON * 16)) {
        dist = d;
        nearby = it;
      }
    }
    kyoten.add(nearby->first, nearby->second);
    P.erase(nearby);
    esa++;
  }
  //
  cout << fixed << setprecision(10) << kyoten.totallength() << endl;
}