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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 5001

struct Point {
  double x, y;
};

typedef Point Vector;

struct Line {
  void set(double x1, double y1, double x2, double y2) {
    p1.x = x1;
    p1.y = y1;
    p2.x = x2;
    p2.y = y2;
  }
  Point p1, p2;
};

typedef Line Segment;

int N, M;
bool is_nenkin[NUM];
Point point[NUM];
double min_dist[NUM];
int index[NUM];

double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }

double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }

Point calc_minus(Point a, Point b) {
  Point ret;

  ret.x = a.x - b.x;
  ret.y = a.y - b.y;

  return ret;
}

double calc_len(Vector a) { return sqrt(a.x * a.x + a.y * a.y); }

double getDistanceLP(Line l, Point p) {
  return fabs(cross(calc_minus(l.p2, l.p1), calc_minus(p, l.p1)) /
              calc_len(calc_minus(l.p2, l.p1)));
}

double getDistanceSP(Segment s, Point p) {
  if (dot(calc_minus(s.p2, s.p1), calc_minus(p, s.p1)) < 0.0)
    return calc_len(calc_minus(p, s.p1));
  if (dot(calc_minus(s.p1, s.p2), calc_minus(p, s.p2)) < 0.0)
    return calc_len(calc_minus(p, s.p2));
  return getDistanceLP(s, p);
}

double calc_dist(int from, int to) {
  return sqrt((point[from].x - point[to].x) * (point[from].x - point[to].x) +
              (point[from].y - point[to].y) * (point[from].y - point[to].y));
}

int main() {

  scanf("%d %d %lf %lf", &N, &M, &point[0].x, &point[0].y);

  is_nenkin[0] = true;
  min_dist[0] = 0;

  for (int i = 1; i <= N; i++) {
    is_nenkin[i] = false;
    min_dist[i] = DBL_MAX;
    scanf("%lf %lf", &point[i].x, &point[i].y);
  }

  int next;
  double minimum = DBL_MAX, tmp_dist;

  for (int i = 1; i <= N; i++) {
    tmp_dist = calc_dist(0, i);
    if (minimum > tmp_dist) {
      minimum = tmp_dist;
      next = i;
    }
  }

  vector<int> Group;

  double ans = minimum;
  is_nenkin[next] = true;
  Group.push_back(0);
  Group.push_back(next);

  Line first_line;
  first_line.set(point[0].x, point[0].y, point[next].x, point[next].y);

  minimum = DBL_MAX;
  for (int i = 1; i <= N; i++) {
    if (is_nenkin[i])
      continue;
    tmp_dist = getDistanceSP(first_line, point[i]);
    min_dist[i] = tmp_dist;
  }

  int count = 1, from;

  while (count < M) {

    minimum = DBL_MAX;
    for (int i = 1; i <= N; i++) {
      if (is_nenkin[i])
        continue;
      if (minimum > min_dist[i]) {
        minimum = min_dist[i];
        next = i;
      }
    }

    minimum = DBL_MAX;
    for (int i = 0; i < Group.size(); i++) {
      tmp_dist = calc_dist(next, Group[i]);
      if (minimum > tmp_dist) {
        minimum = tmp_dist;
        from = Group[i];
      } else if (fabs(minimum - tmp_dist) < EPS) {
        if (from > Group[i]) {
          from = Group[i];
        }
      }
    }

    ans += minimum;
    count++;
    if (count == M)
      break;

    is_nenkin[next] = true;
    Group.push_back(next);
    Line new_line;
    new_line.set(point[from].x, point[from].y, point[next].x, point[next].y);

    for (int i = 1; i <= N; i++) {
      if (is_nenkin[i])
        continue;

      min_dist[i] = min(min_dist[i], getDistanceSP(new_line, point[i]));
    }
  }

  printf("%.10lf\\n", ans);

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 5001

struct Point {
  double x, y;
};

typedef Point Vector;

struct Line {
  void set(double x1, double y1, double x2, double y2) {
    p1.x = x1;
    p1.y = y1;
    p2.x = x2;
    p2.y = y2;
  }
  Point p1, p2;
};

typedef Line Segment;

int N, M;
bool is_nenkin[NUM];
Point point[NUM];
int index[NUM];

double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }

double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }

Point calc_minus(Point a, Point b) {
  Point ret;

  ret.x = a.x - b.x;
  ret.y = a.y - b.y;

  return ret;
}

double calc_len(Vector a) { return sqrt(a.x * a.x + a.y * a.y); }

double getDistanceLP(Line l, Point p) {
  return fabs(cross(calc_minus(l.p2, l.p1), calc_minus(p, l.p1)) /
              calc_len(calc_minus(l.p2, l.p1)));
}

double getDistanceSP(Segment s, Point p) {
  if (dot(calc_minus(s.p2, s.p1), calc_minus(p, s.p1)) < 0.0)
    return calc_len(calc_minus(p, s.p1));
  if (dot(calc_minus(s.p1, s.p2), calc_minus(p, s.p2)) < 0.0)
    return calc_len(calc_minus(p, s.p2));
  return getDistanceLP(s, p);
}

double calc_dist(int from, int to) {
  return sqrt((point[from].x - point[to].x) * (point[from].x - point[to].x) +
              (point[from].y - point[to].y) * (point[from].y - point[to].y));
}

int main() {

  scanf("%d %d %lf %lf", &N, &M, &point[0].x, &point[0].y);

  is_nenkin[0] = true;
  for (int i = 1; i <= N; i++) {
    is_nenkin[i] = false;
    scanf("%lf %lf", &point[i].x, &point[i].y);
  }

  int next;
  double minimum = DBL_MAX, tmp_dist;

  for (int i = 1; i <= N; i++) {
    tmp_dist = calc_dist(0, i);
    if (minimum > tmp_dist) {
      minimum = tmp_dist;
      next = i;
    }
  }

  vector<int> Group;

  double ans = minimum;
  is_nenkin[next] = true;
  Group.push_back(0);
  Group.push_back(next);

  vector<Line> NET;
  Line first_line;
  first_line.set(point[0].x, point[0].y, point[next].x, point[next].y);
  NET.push_back(first_line);

  int count = 1, from;

  while (count < M) {

    minimum = DBL_MAX;
    for (int i = 0; i < NET.size(); i++) {
      for (int k = 1; k <= N; k++) {
        if (is_nenkin[k])
          continue;

        tmp_dist = getDistanceSP(NET[i], point[k]);
        if (minimum > tmp_dist) {
          minimum = tmp_dist;
          next = k;
        } else if (fabs(minimum - tmp_dist) < EPS && next > k) {
          next = k;
        }
      }
    }

    minimum = DBL_MAX;
    for (int i = 0; i < Group.size(); i++) {
      tmp_dist = calc_dist(next, Group[i]);
      if (minimum > tmp_dist) {
        minimum = tmp_dist;
        from = Group[i];
      } else if (fabs(minimum - tmp_dist) < EPS) {
        if (from > Group[i]) {
          from = Group[i];
        }
      }
    }

    ans += minimum;
    count++;
    if (count == M)
      break;

    is_nenkin[next] = true;
    Group.push_back(next);
    Line new_line;
    new_line.set(point[from].x, point[from].y, point[next].x, point[next].y);
    NET.push_back(new_line);
  }

  printf("%.10lf\\n", ans);

  return 0;
}