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

/*
 * c.cc:
 */

#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 <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 5000;
const int INF = 1 << 30;
const double DINF = 1e60;

/* 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) {}

  bool operator==(const Pt pt) const { return x == pt.x && y == pt.y; }
  Pt<T> operator+(const Pt pt) const { return Pt<T>(x + pt.x, y + pt.y); }
  Pt<T> operator-() const { return Pt<T>(-x, -y); }
  Pt<T> operator-(const Pt pt) const { return Pt<T>(x - pt.x, y - pt.y); }
  Pt<T> operator*(T t) const { return Pt<T>(x * t, y * t); }
  Pt<T> operator/(T t) const { return Pt<T>(x / t, y / t); }
  T dot(Pt v) const { return x * v.x + y * v.y; }
  T cross(Pt v) const { return x * v.y - y * v.x; }
  T d2() { return x * x + y * y; }
  double d() { return sqrt(d2()); }

  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);
  }
  void print() { print("%.6lf"); }
};

typedef Pt<int> pt;

/* global variables */

pt pts[MAX_N + 1];
bool used[MAX_N + 1];
double ed2s[MAX_N + 1];

/* subroutines */

double ed2(int a, int b, int c) {
  pt vab(pts[b] - pts[a]), vac(pts[c] - pts[a]), vbc(pts[c] - pts[b]);
  if (vab.dot(vac) <= 0)
    return (double)vac.d2();
  if (vab.dot(vbc) >= 0)
    return (double)vbc.d2();

  int cr = vab.cross(vac);
  return (double)cr * cr / vab.d2();
}

int pd2(int i, int j) { return (pts[j] - pts[i]).d2(); }

/* main */

int main() {
  int n, m;
  cin >> n >> m;

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

  ed2s[0] = DINF;
  used[0] = true;
  double mind2 = INF;
  int nxti = -1;
  for (int i = 1; i <= n; i++) {
    ed2s[i] = (double)pd2(0, i);
    if (mind2 > ed2s[i])
      mind2 = ed2s[i], nxti = i;
  }

  double sum = 0.0;

  while (m--) {
    int minpd2 = INF, minpi = -1;
    for (int i = 0; i <= n; i++)
      if (used[i]) {
        int pd2i = pd2(nxti, i);
        if (minpd2 > pd2i)
          minpd2 = pd2i, minpi = i;
      }
    // printf("nxti=%d, minpi=%d, minpd2=%d\\n", nxti, minpi, minpd2);

    sum += sqrt((double)minpd2);
    ed2s[nxti] = DINF;
    used[nxti] = true;

    double mined2 = DINF;
    int minei = -1;
    for (int i = 1; i <= n; i++)
      if (!used[i]) {
        double ed2i = ed2(nxti, minpi, i);
        if (ed2s[i] > ed2i)
          ed2s[i] = ed2i;
        if (mined2 > ed2s[i])
          mined2 = ed2s[i], minei = i;
      }

    nxti = minei;
  }

  printf("%.10lf\\n", sum);
  return 0;
}

Error: MLE

Fixed submission:

/*
 * c.cc:
 */

#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 <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 5000;
const double DINF = 1e60;

/* 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) {}

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

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

  Pt<T> rot90() { return Pt<T>(-y, x); }

  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);
  }
  void print() { print("%.6lf"); }
};

typedef Pt<double> pt;

struct Stat {
  double d2;
  int i;
  Stat() {}
  Stat(double _d2, int _i) : d2(_d2), i(_i) {}
  bool operator<(const Stat &s) const {
    return d2 > s.d2 || (d2 == s.d2 && i > s.i);
  }
};

/* global variables */

pt pts[MAX_N + 1];
bool used[MAX_N + 1];

/* subroutines */

double ed2(pt a, pt b, pt c) {
  pt vab = b - a, vac = c - a, vbc = c - b;
  if (vab.dot(vac) <= 0.0)
    return vac.d2();
  if (vab.dot(vbc) >= 0.0)
    return vbc.d2();

  double cr = vab.cross(vac);
  return cr * cr / vab.d2();
}

inline double d2(int i, int j) { return (pts[j] - pts[i]).d2(); }

/* main */

int main() {
  int n, m;
  cin >> n >> m;

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

  priority_queue<Stat> q;
  used[0] = true;
  for (int i = 1; i <= n; i++)
    q.push(Stat(d2(0, i), i));

  double sum = 0.0;

  for (int i = 0; i < m; i++) {
    Stat u;
    do {
      u = q.top();
      q.pop();
    } while (used[u.i]);
    // printf("  d2=%lf,i=%d\\n", u.d2, u.i);

    used[u.i] = true;

    double mind2 = DINF;
    int mini = -1;
    for (int j = 0; j <= n; j++)
      if (u.i != j && used[j]) {
        double d2j = d2(u.i, j);
        if (mind2 > d2j)
          mind2 = d2j, mini = j;
      }

    sum += sqrt(mind2);

    for (int j = 1; j <= n; j++)
      if (!used[j]) {
        double ed2j = ed2(pts[u.i], pts[mini], pts[j]);
        q.push(Stat(ed2j, j));
      }
  }

  printf("%.10lf\\n", sum);
  return 0;
}