Problem p01698 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define FF first
#define SS second
template <class S, class T> istream &operator>>(istream &is, pair<S, T> &p) {
  return is >> p.FF >> p.SS;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << p.FF << " " << p.SS;
}
template <class T> void maxi(T &x, T y) {
  if (x < y)
    x = y;
}
template <class T> void mini(T &x, T y) {
  if (x > y)
    x = y;
}

const double EPS = 1e-10;
const double PI = acos(-1.0);
const LL MOD = 1e9 + 7;

struct P {
  double x, y, z;
  P(double x_ = 0., double y_ = 0., double z_ = 0.) : x(x_), y(y_), z(z_) {}
  double norm() const { return sqrt(x * x + y * y + z * z); }

  P operator+(const P &p2) const { return P(x + p2.x, y + p2.y, z + p2.z); }
  P operator-(const P &p2) const { return P(x - p2.x, y - p2.y, z - p2.z); }

  P operator*(double sc) const { return P(x * sc, y * sc, z * sc); }
};

double solve(const P &p1, const P &p2, const P &dv1, const P &dv2, double r1,
             double r2, double dr1, double dr2, double ub) {
  double lb = 0., md = 1e9;
  REP(i, 100) {
    double ts[2] = {(lb * 2 + ub) / 3., (lb + ub * 2) / 3.};
    double ys[2];
    REP(j, 2) {
      P c1 = p1 + dv1 * ts[j];
      P c2 = p2 + dv2 * ts[j];
      double dist = (c1 - c2).norm();
      double tr1 = r1 - dr1 * ts[j];
      double tr2 = r2 - dr2 * ts[j];
      ys[j] = dist - tr1 - tr2;
      maxi(ys[j], 0.);
    }
    if (ys[0] <= ys[1]) {
      ub = ts[1];
      md = ys[0];
    } else {
      lb = ts[0];
      md = ys[1];
    }
  }
  if (md > EPS)
    return 1e9;

  return lb;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N;
  while (cin >> N, N) {
    vector<P> ps(N), dv(N);
    vector<double> rs(N), dr(N);
    REP(i, N) {
      cin >> ps[i].x >> ps[i].y >> ps[i].z >> dv[i].x >> dv[i].y >> dv[i].z >>
          rs[i] >> dr[i];
    }

    vector<double> ans(N);
    vector<bool> col(N);
    REP(i, N) ans[i] = rs[i] / dr[i];
    while (true) {
      int i1 = -1, i2;
      double at = 1e9;
      REP(i, N) REP(j, i) {
        if (col[i] || col[j])
          continue;
        double t = solve(ps[i], ps[j], dv[i], dv[j], rs[i], rs[j], dr[i], dr[j],
                         min(ans[i], ans[j]));
        if (at > t && t < ans[i] - EPS && t < ans[j] - EPS) {
          i1 = i;
          i2 = j;
          at = t;
        }
      }
      if (i1 < 0)
        break;
      col[i1] = col[i2] = true;
      mini(ans[i1], at);
      mini(ans[i2], at);
    }

    REP(i, N) cout << fixed << setprecision(9) << ans[i] << endl;
  }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define FF first
#define SS second
template <class S, class T> istream &operator>>(istream &is, pair<S, T> &p) {
  return is >> p.FF >> p.SS;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << p.FF << " " << p.SS;
}
template <class T> void maxi(T &x, T y) {
  if (x < y)
    x = y;
}
template <class T> void mini(T &x, T y) {
  if (x > y)
    x = y;
}

const double EPS = 1e-10;
const double PI = acos(-1.0);
const LL MOD = 1e9 + 7;

struct P {
  double x, y, z;
  P(double x_ = 0., double y_ = 0., double z_ = 0.) : x(x_), y(y_), z(z_) {}
  double norm() const { return sqrt(x * x + y * y + z * z); }

  P operator+(const P &p2) const { return P(x + p2.x, y + p2.y, z + p2.z); }
  P operator-(const P &p2) const { return P(x - p2.x, y - p2.y, z - p2.z); }

  P operator*(double sc) const { return P(x * sc, y * sc, z * sc); }
};

double solve(const P &p1, const P &p2, const P &dv1, const P &dv2, double r1,
             double r2, double dr1, double dr2, double ub) {
  double lb = 0., md = 1e9;
  REP(i, 100) {
    double ts[2] = {(lb * 2 + ub) / 3., (lb + ub * 2) / 3.};
    double ys[2];
    REP(j, 2) {
      P c1 = p1 + dv1 * ts[j];
      P c2 = p2 + dv2 * ts[j];
      double dist = (c1 - c2).norm();
      double tr1 = r1 - dr1 * ts[j];
      double tr2 = r2 - dr2 * ts[j];
      ys[j] = dist - tr1 - tr2;
      maxi(ys[j], 0.);
    }
    if (ys[0] <= ys[1]) {
      ub = ts[1];
      md = ys[0];
    } else {
      lb = ts[0];
      md = ys[1];
    }
  }
  if (md > EPS)
    return 1e9;

  return lb;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N;
  while (cin >> N, N) {
    vector<P> ps(N), dv(N);
    vector<double> rs(N), dr(N);
    REP(i, N) {
      cin >> ps[i].x >> ps[i].y >> ps[i].z >> dv[i].x >> dv[i].y >> dv[i].z >>
          rs[i] >> dr[i];
    }

    vector<double> ans(N);
    vector<bool> col(N);
    REP(i, N) ans[i] = rs[i] / dr[i];
    priority_queue<pair<double, PII>> pq;
    REP(i, N) REP(j, i) {
      double t = solve(ps[i], ps[j], dv[i], dv[j], rs[i], rs[j], dr[i], dr[j],
                       min(ans[i], ans[j]));
      pq.push(MP(-t, MP(i, j)));
    }

    while (!pq.empty()) {
      double at = -pq.top().FF;
      PII p = pq.top().SS;
      pq.pop();
      if (col[p.FF] || col[p.SS])
        continue;
      col[p.FF] = col[p.SS] = true;
      mini(ans[p.FF], at);
      mini(ans[p.SS], at);
    }

    REP(i, N) cout << fixed << setprecision(9) << ans[i] << endl;
  }

  return 0;
}