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

#include <algorithm>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <utility>
#include <vector>
#define eps 1e-8
#define double long double

using namespace std;
typedef pair<double, pair<int, int>> Event;

struct vec3d {
  double x, y, z;
  vec3d() {}
  vec3d(double x, double y, double z) { this->x = x, this->y = y, this->z = z; }
  double add(double a, double b) {
    if (fabs(a + b) < eps * (fabs(a) + fabs(b)))
      return 0.0;
    return a + b;
  }
  vec3d operator+(vec3d ope) {
    return vec3d(add(x, ope.x), add(y, ope.y), add(z, ope.z));
  }
  vec3d operator-(vec3d ope) {
    return vec3d(add(x, -ope.x), add(y, -ope.y), add(z, -ope.z));
  }
  vec3d operator*(double t) { return vec3d(x * t, y * t, z * t); }
  vec3d operator/(double t) { return vec3d(x / t, y / t, z / t); }
  double dot(vec3d ope) { return add(add(x * ope.x, y * ope.y), z * ope.z); }
  /*double cross(vec3d ope){  // NOT IMPLEMENTED
          return add(x*ope.y, -y*ope.x);
  }*/
  double norm() {
    double d2 = dot(*this);
    if (d2 > 0)
      return sqrt(d2);
    return 0.0;
  }
};

double distPP(vec3d p, vec3d q) { return (p - q).norm(); }

vector<Event> vec;

int n;
vec3d p[205], v[205];
double r[205], vr[205];
double dis[205], ans[205];
bool used[205];

int main(void) {
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    for (int i = 1; i <= n; i++) {
      cin >> p[i].x >> p[i].y >> p[i].z;
      cin >> v[i].x >> v[i].y >> v[i].z;
      cin >> r[i] >> vr[i];
    }
    for (int i = 1; i <= n; i++)
      dis[i] = r[i] / vr[i];

    vec.clear();
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        if (i >= j)
          continue;
        vec3d P = p[i] - p[j], V = v[i] - v[j];
        double R = r[i] + r[j], VR = vr[i] + vr[j];
        double t = min(dis[i], dis[j]);
        double A = V.dot(V) - VR * VR;
        double B = 2 * P.dot(V) + 2 * R * VR;
        double C = P.dot(P) - R * R;
        double D = B * B - 4 * A * C;
        if (fabs(A) < eps) {
          if (fabs(B) < eps) {
            if (fabs(C) < eps)
              vec.push_back(make_pair(0, make_pair(i, j)));
            continue;
          }
          double x = -C / B;
          if (x >= -eps && x <= t + eps)
            vec.push_back(make_pair(x, make_pair(i, j)));
          continue;
        }
        if (D < 0)
          continue;
        double x1 = (-B - sqrt(D)) / (2 * A);
        double x2 = (-B + sqrt(D)) / (2 * A);
        if (x1 > x2)
          swap(x1, x2);
        if (x1 >= -eps && x1 <= t + eps) {
          vec.push_back(make_pair(x1, make_pair(i, j)));
          continue;
        }
        if (x2 >= -eps && x2 <= t + eps) {
          vec.push_back(make_pair(x2, make_pair(i, j)));
        }
      }
    }
    for (int i = 1; i <= n; i++)
      vec.push_back(make_pair(dis[i], make_pair(i, i)));
    sort(vec.begin(), vec.end());

    for (int i = 1; i <= n; i++)
      used[i] = false;
    for (int i = 0; i < vec.size(); i++) {
      int u = vec[i].second.first, v = vec[i].second.second;
      if (used[u] || used[v])
        continue;
      ans[u] = ans[v] = vec[i].first;
      used[u] = used[v] = true;
    }

    for (int i = 1; i <= n; i++)
      printf("%.11Lf\\n", ans[i]);
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <math.h>
#include <stdio.h>
#define INF 1000

struct vector3D {
  double x, y, z;
  double norm() { return sqrt(x * x + y * y + z * z); }
};

int main(void) {
  int n;
  vector3D p[200], v[200];
  double r[200], vr[200];

  double time[200];
  double table[200][200];

  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;

    for (int i = 0; i < n; i++) {
      scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &p[i].x, &p[i].y, &p[i].z,
            &v[i].x, &v[i].y, &v[i].z, &r[i], &vr[i]);
    }

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        table[i][j] = INF;
      }
    }
    for (int i = 0; i < n; i++) {
      time[i] = -1;
      table[i][i] = r[i] / vr[i];
    }

    while (1) {

      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (i >= j)
            continue;

          if (time[i] > 0 || time[j] > 0) {
            table[i][j] = INF;
            continue;
          }

          vector3D dp, dv;
          dp.x = p[i].x - p[j].x;
          dp.y = p[i].y - p[j].y;
          dp.z = p[i].z - p[j].z;
          dv.x = v[i].x - v[j].x;
          dv.y = v[i].y - v[j].y;
          dv.z = v[i].z - v[j].z;

          double R = r[i] + r[j];
          double VR = vr[i] + vr[j];

          double a = dv.norm() * dv.norm() - VR * VR;
          double b = 2 * (dp.x * dv.x + dp.y * dv.y + dp.z * dv.z) + 2 * R * VR;
          double c = dp.norm() * dp.norm() - R * R;
          double D = b * b - 4 * a * c;

          if (D < 0.0)
            table[i][j] = INF;
          else if (D == 0.0)
            table[i][j] = -b / (2 * a);
          else {
            table[i][j] = (-b - sqrt(D)) / (2 * a);
            if (table[i][j] < 0)
              table[i][j] = (-b + sqrt(D)) / (2 * a);
            if (table[i][j] < 0)
              table[i][j] = INF;
          }
        }
      }

      double min = INF;
      int min_i, min_j;
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (min > table[i][j]) {
            min = table[i][j];
            min_i = i;
            min_j = j;
          }
        }
      }
      if (min == INF)
        break;

      time[min_i] = time[min_j] = min;
      table[min_i][min_i] = table[min_j][min_j] = INF;
    }

    for (int i = 0; i < n; i++)
      printf("%.10f\\n", time[i]);
  }

  return 0;
}