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

// 基本テンプレート

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

using ld = double;
using P = complex<ld>;
using G = vector<P>;
const ld pi = acos(-1);
const ld eps = 1e-10;
const ld inf = 1e12;

ld cross(const P &a, const P &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}
ld dot(const P &a, const P &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}

using C = pair<ld, P>;
#define rad first
#define pnt second

C smallest_enclosing_disc(vector<P> ps) {
  auto c3 = [](const P &a, const P &b, const P &c) {
    ld A = norm(b - c);
    ld B = norm(c - a);
    ld C = norm(a - b);
    ld S = abs(cross(b - a, c - a));
    P p = (A * (B + C - A) * a + B * (C + A - B) * b + C * (A + B - C) * c) /
          (4 * S * S);
    ld r = abs(p - a);
    return make_pair(r, p);
  };

  auto c2 = [](const P &a, const P &b) {
    P c = (a + b) / (ld)2;
    ld r = abs(a - c);
    return make_pair(r, c);
  };

  auto in_circle = [](const P &a, const C &c) {
    return norm(a - c.pnt) <= c.rad * c.rad + eps;
  };

  int n = ps.size();
  if (n == 1)
    return make_pair(0, ps[0]);
  random_shuffle(ps.begin(), ps.end());
  C c = c2(ps[0], ps[1]);
  for (int i = 2; i < n; ++i) {
    if (!in_circle(ps[i], c)) {
      c = c2(ps[0], ps[i]);
      for (int j = 1; j < i; ++j) {
        if (!in_circle(ps[j], c)) {
          c = c2(ps[j], ps[i]);
          for (int k = 0; k < j; ++k) {
            if (!in_circle(ps[k], c)) {
              c = c3(ps[i], ps[j], ps[k]);
            }
          }
        }
      }
    }
  }
  return c;
}

double circle_r[1 << 14];
double dp[1 << 14][20];

signed main() {
  int N, M;
  cin >> N >> M;
  vector<P> ps;
  for (int i = 0; i < N; i++) {
    double x, y;
    cin >> x >> y;
    ps.push_back(P(x, y));
  }

  for (int bit = 1; bit < (1 << N); bit++) {
    vector<P> tmp;
    for (int i = 0; i < N; i++) {
      if (bit >> i & 1)
        tmp.push_back(ps[i]);
    }
    circle_r[bit] = smallest_enclosing_disc(tmp).first;
    // printf("circle_r[%lld] = %.12f\\n", bit, circle_r[bit]);
  }

  for (int i = 0; i < (1 << N); i++) {
    fill(dp[i], dp[i] + 20, inf);
  }

  double ans = inf;
  dp[0][0] = 0;
  for (int k = 0; k < M; k++) {
    for (int bit = 0; bit < (1 << N); bit++) {
      int rest = (bit ^ ((1 << N) - 1));
      for (int nxt = rest; nxt > 0; nxt = (nxt - 1) & rest) {
        int nbit = bit | nxt;
        chmin(dp[nbit][k + 1], max(dp[bit][k], circle_r[nxt]));
        if (nbit == (1 << N) - 1)
          chmin(ans, dp[nbit][k + 1]);
      }
    }
  }
  printf("%.12f\\n", ans);
  return 0;
}


Error: TLE

Fixed submission:

// 基本テンプレート

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

using ld = double;
using P = complex<ld>;
using G = vector<P>;
const ld pi = acos(-1);
const ld eps = 1e-10;
const ld inf = 1e12;

ld cross(const P &a, const P &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}
ld dot(const P &a, const P &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}

using C = pair<ld, P>;
#define rad first
#define pnt second

C smallest_enclosing_disc(vector<P> ps) {
  auto c3 = [](const P &a, const P &b, const P &c) {
    ld A = norm(b - c);
    ld B = norm(c - a);
    ld C = norm(a - b);
    ld S = abs(cross(b - a, c - a));
    P p = (A * (B + C - A) * a + B * (C + A - B) * b + C * (A + B - C) * c) /
          (4 * S * S);
    ld r = abs(p - a);
    return make_pair(r, p);
  };

  auto c2 = [](const P &a, const P &b) {
    P c = (a + b) / (ld)2;
    ld r = abs(a - c);
    return make_pair(r, c);
  };

  auto in_circle = [](const P &a, const C &c) {
    return norm(a - c.pnt) <= c.rad * c.rad + eps;
  };

  int n = ps.size();
  if (n == 1)
    return make_pair(0, ps[0]);
  random_shuffle(ps.begin(), ps.end());
  C c = c2(ps[0], ps[1]);
  for (int i = 2; i < n; ++i) {
    if (!in_circle(ps[i], c)) {
      c = c2(ps[0], ps[i]);
      for (int j = 1; j < i; ++j) {
        if (!in_circle(ps[j], c)) {
          c = c2(ps[j], ps[i]);
          for (int k = 0; k < j; ++k) {
            if (!in_circle(ps[k], c)) {
              c = c3(ps[i], ps[j], ps[k]);
            }
          }
        }
      }
    }
  }
  return c;
}

double circle_r[1 << 14];
double dp[1 << 14][20];
double solve(int bit, int k) {
  if (dp[bit][k] + eps > inf)
    return dp[bit][k];
  if (k == 1)
    return dp[bit][k] = circle_r[bit];
  for (int part = bit; part > 0; part = (part - 1) & bit) {
    int nbit = bit ^ part;
    chmin(dp[bit][k], max(solve(nbit, k - 1), circle_r[part]));
    // printf("lhs(%lld, %lld) = %.12f, rhs(%lld) = %.12f\\n", nbit, k-1,
    // dp[nbit][k-1], part, circle_r[part]);
  }
  // printf("dp[%lld][%lld] = %.12f\\n", bit, k, dp[bit][k]);
  return dp[bit][k];
}

signed main() {
  int N, M;
  cin >> N >> M;
  vector<P> ps;
  for (int i = 0; i < N; i++) {
    double x, y;
    cin >> x >> y;
    ps.push_back(P(x, y));
  }

  for (int bit = 1; bit < (1 << N); bit++) {
    vector<P> tmp;
    for (int i = 0; i < N; i++) {
      if (bit >> i & 1)
        tmp.push_back(ps[i]);
    }
    circle_r[bit] = smallest_enclosing_disc(tmp).first;
    // printf("circle_r[%lld] = %.12f\\n", bit, circle_r[bit]);
  }

  for (int i = 0; i < (1 << N); i++) {
    fill(dp[i], dp[i] + 20, inf);
  }
  printf("%.12f\\n", solve((1 << N) - 1, M));
  return 0;
}