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


#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pint;
typedef vector<int> vint;
typedef vector<pint> vpint;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, f, n) for (int i = (f); i < (n); i++)
#define each(it, v)                                                            \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
template <class T, class U> inline void chmin(T &t, U f) {
  if (t > f)
    t = f;
}
template <class T, class U> inline void chmax(T &t, U f) {
  if (t < f)
    t = f;
}

const double EPS = 1e-6;
const double INF = 1e10;

typedef complex<double> Point;
typedef complex<double> Vector;

struct Line {
  Point a, b;
  Line() {}
  Line(const Point &_a, const Point &_b) {
    a = _a;
    b = _b;
  }
};

// Line????????????
struct Segment {
  Point a, b;
  Segment() {}
  Segment(const Point &_a, const Point &_b) {
    a = _a;
    b = _b;
  }
};

istream &operator>>(istream &is, Point &p) {
  double x, y;
  is >> x >> y;
  p.real(x);
  p.imag(y);
  return is;
}

Segment ToSegment(const Line l) { return Segment(l.a, l.b); }

Line ToLine(const Segment s) { return Line(s.a, s.b); }

double dot(const Vector &a, const Vector &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}

double cross(const Vector &a, const Vector &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

double GetDistance(const Line &l, const Point &p) {
  return abs(cross(l.a - l.b, p - l.a) / abs(l.b - l.a));
}

double GetDistance(const Segment &s, const Point &p) {
  if (dot(s.b - s.a, p - s.a) < 0.0)
    return abs(p - s.a);
  if (dot(s.a - s.b, p - s.b) < 0.0)
    return abs(p - s.b);
  return GetDistance(ToLine(s), p);
}

int N, M;
Point p[11111];
bool used[11111];
double dist[11111];
signed main() {
  cin >> N >> M;
  rep(i, N + 1) cin >> p[i];

  used[0] = true;
  double ans = 0;
  rep(i, N + 1) dist[i] = abs(p[i] - p[0]);
  rep(t, M) {
    int mi = -1;
    for (int i = N; i >= 0; i--) {
      if (used[i])
        continue;
      if (mi == -1)
        mi = i;
      else if (dist[mi] + EPS > dist[i])
        mi = i;
    }
    double mincost = INF;
    int vv = -1;
    for (int i = N; i >= 0; i--) {
      if (!used[i])
        continue;
      double tmp = abs(p[mi] - p[i]);
      if (mincost + EPS > tmp) {
        mincost = tmp;
        vv = i;
      }
    }

    ans += mincost;
    used[mi] = true;
    Segment s(p[mi], p[vv]);
    rep(i, N + 1) {
      if (used[i])
        continue;
      chmin(dist[i], GetDistance(s, p[i]));
    }
  }

  printf("%.20f\\n", ans);
}

Error: MLE

Fixed submission:


#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pint;
typedef vector<int> vint;
typedef vector<pint> vpint;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, f, n) for (int i = (f); i < (n); i++)
#define each(it, v)                                                            \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
template <class T, class U> inline void chmin(T &t, U f) {
  if (t > f)
    t = f;
}
template <class T, class U> inline void chmax(T &t, U f) {
  if (t < f)
    t = f;
}

const double EPS = 1e-6;
const double INF = 1e10;

typedef complex<double> Point;
typedef complex<double> Vector;

struct Line {
  Point a, b;
  Line() {}
  Line(const Point &_a, const Point &_b) {
    a = _a;
    b = _b;
  }
};

// Line????????????
struct Segment {
  Point a, b;
  Segment() {}
  Segment(const Point &_a, const Point &_b) {
    a = _a;
    b = _b;
  }
};

istream &operator>>(istream &is, Point &p) {
  double x, y;
  is >> x >> y;
  p.real(x);
  p.imag(y);
  return is;
}

Segment ToSegment(const Line l) { return Segment(l.a, l.b); }

Line ToLine(const Segment s) { return Line(s.a, s.b); }

double dot(const Vector &a, const Vector &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}

double cross(const Vector &a, const Vector &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

double GetDistance(const Line &l, const Point &p) {
  return abs(cross(l.a - l.b, p - l.a) / abs(l.b - l.a));
}

double GetDistance(const Segment &s, const Point &p) {
  if (dot(s.b - s.a, p - s.a) < 0.0)
    return abs(p - s.a);
  if (dot(s.a - s.b, p - s.b) < 0.0)
    return abs(p - s.b);
  return GetDistance(ToLine(s), p);
}

int N, M;
Point p[11111];

typedef pair<double, int> node;
bool used[11111];
signed main() {
  cin >> N >> M;
  rep(i, N + 1) cin >> p[i];

  priority_queue<node, vector<node>, greater<node>> que;
  reps(i, 1, N + 1) { que.push(node(abs(p[i] - p[0]), i)); }
  used[0] = true;
  double ans = 0;
  rep(t, M) {
    while (true) {
      int v = que.top().se;
      double c = que.top().fi;
      que.pop();
      if (used[v])
        continue;
      double mi = INF;
      int vv = -1;
      rep(i, N + 1) {
        if (!used[i])
          continue;
        if (mi > abs(p[v] - p[i])) {
          mi = abs(p[v] - p[i]);
          vv = i;
        }
      }
      used[v] = true;
      ans += mi;
      reps(i, 1, N + 1) {
        if (used[i])
          continue;

        Segment s(p[v], p[vv]);

        double nc = GetDistance(s, p[i]);
        que.push(node(nc, i));
      }
      break;
    }
  }

  printf("%.20f\\n", ans);
}