Problem p00708 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;

const int MAX_E = 200 * 100;
const int MAX_N = 200 * 100;
double data[200][4];

struct UnionFind {
  int par[MAX_N];
  int rank[MAX_N];

  void init(int n) {
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      rank[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};
struct Edge {
  int u, w;
  double cost;
};
bool comp(const Edge &e1, const Edge &e2) { return e1.cost < e2.cost; }

Edge es[MAX_E];
int v, e;
UnionFind uf;

int main() {
  for (;;) {
    int n;
    scanf("%d", &n);
    if (n == 0)
      return 0;
    // double data[n][4];
    e = n * (n - 1) / 2;
    v = n;

    uf.init(n * (n - 1) / 2);

    for (int i = 0; i < n; i++) {
      cin >> data[i][0] >> data[i][1] >> data[i][2] >> data[i][3];
    }

    int count = 0;
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        Edge et;
        et.u = i;
        et.w = j;
        double length =
            sqrt(((data[i][0] - data[j][0]) * (data[i][0] - data[j][0])) +
                 ((data[i][1] - data[j][1]) * (data[i][1] - data[j][1])) +
                 ((data[i][2] - data[j][2]) * (data[i][2] - data[j][2]))) -
            data[i][3] - data[j][3];
        if (length < 0.0) {
          uf.unite(i, j);
          length = 0.0;
        }
        et.cost = length;
        es[count++] = et;
      }
    }

    // printf("A:%d %d\\n",count,e);

    sort(es, es + e, comp);
    double ans = 0.0;

    for (int i = 0; i < e; ++i) {
      Edge et = es[i];
      // printf("B:%f\\n",et.cost);
      if (!uf.same(et.u, et.w)) {
        uf.unite(et.u, et.w);
        ans += et.cost;
      }
    }

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


Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;

const int MAX_E = 200 * 100;
const int MAX_N = 200;

struct UnionFind {
  int par[MAX_N];
  int rank[MAX_N];

  void init(int n) {
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      rank[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};
struct Edge {
  int u, w;
  double cost;
};
bool comp(const Edge &e1, const Edge &e2) { return e1.cost < e2.cost; }

Edge es[MAX_E];
int v, e;

int main() {
  for (;;) {
    int n;
    scanf("%d", &n);
    if (n == 0)
      return 0;
    double data[n][4];
    e = n * (n - 1) / 2;
    v = n;

    UnionFind uf;
    uf.init(n * (n - 1) / 2);

    for (int i = 0; i < n; i++) {
      cin >> data[i][0] >> data[i][1] >> data[i][2] >> data[i][3];
    }

    int count = 0;
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        Edge et;
        et.u = i;
        et.w = j;
        double length =
            sqrt(((data[i][0] - data[j][0]) * (data[i][0] - data[j][0])) +
                 ((data[i][1] - data[j][1]) * (data[i][1] - data[j][1])) +
                 ((data[i][2] - data[j][2]) * (data[i][2] - data[j][2]))) -
            data[i][3] - data[j][3];
        if (length < 0.0) {
          uf.unite(i, j);
          length = 0.0;
        }
        et.cost = length;
        es[count++] = et;
      }
    }

    // printf("A:%d %d\\n",count,e);

    sort(es, es + e, comp);
    double ans = 0.0;

    for (int i = 0; i < e; ++i) {
      Edge et = es[i];
      // printf("B:%f\\n",et.cost);
      if (!uf.same(et.u, et.w)) {
        uf.unite(et.u, et.w);
        ans += et.cost;
      }
    }

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