Problem p03682 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define FILL0(x) memset(x, 0, sizeof(x))

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

const ll MAX = 100010;

class UnionFind {
private:
  int par[MAX];
  int rank[MAX];

public:
  UnionFind(int N);
  int find(int x);
  void unite(int x, int y);
  bool same(int x, int y);
};

// コンストラクタ
UnionFind::UnionFind(int N) {
  for (int i = 0; i < N; i++) {
    par[i] = i;
    rank[i] = 0;
  }
}

// 木の根を求める
int UnionFind::find(int x) {
  if (par[x] == x) {
    return x;
  } else {
    return par[x] = find(par[x]);
  }
}
// 位数の大きい木に統合する
void UnionFind::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]++;
    }
  }
}

// 同じ根を持つならtrueを返す
bool UnionFind::same(int x, int y) { return find(x) == find(y); }

struct edge {
  int from, to, cost;
};

struct point {
  ll x, y;
  int no;
};

bool comp(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }

bool pcomp1(const point &p1, const point &p2) { return p1.x < p2.x; }

bool pcomp2(const point &p1, const point &p2) { return p1.y < p2.y; }

edge es[MAX];
point p[MAX];

int V, E;

int kruskal() {
  sort(es, es + E, comp);
  UnionFind *tree = new UnionFind(V);
  int res = 0;
  for (int i = 0; i < E; i++) {
    edge e = es[i];
    if (!tree->same(e.from, e.to)) {
      tree->unite(e.from, e.to);
      res += e.cost;
    }
  }
  return res;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(20);

  int N;
  cin >> N;

  V = N;
  E = 2 * N - 2;

  rep(i, N) {
    cin >> p[i].x >> p[i].y;
    p[i].no = i;
  }

  sort(p, p + N, pcomp1);

  rep(i, N - 1) {
    es[i].cost = min(abs(p[i].x - p[i + 1].x), abs(p[i].y - p[i + 1].y));
    es[i].from = p[i].no;
    es[i].to = p[i + 1].no;
  }

  sort(p, p + N, pcomp2);

  for (int i = 0; i < N - 1; i++) {
    int j = i + N - 1;
    es[j].cost = min(abs(p[i].x - p[i + 1].x), abs(p[i].y - p[i + 1].y));
    es[j].from = p[i].no;
    es[j].to = p[i + 1].no;
  }

  cout << kruskal() << endl;

  return 0;
}

// cout << setprecision(13);
// next_permutation();
//__gcd();
// reverse();
// set ,tuple ,pair;
// bitset
// vector.find


Fixed submission:
#include <bits/stdc++.h>

#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define FILL0(x) memset(x, 0, sizeof(x))

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

const ll MAX = 200010;

class UnionFind {
private:
  int par[MAX];
  int rank[MAX];

public:
  UnionFind(int N);
  int find(int x);
  void unite(int x, int y);
  bool same(int x, int y);
};

// コンストラクタ
UnionFind::UnionFind(int N) {
  for (int i = 0; i < N; i++) {
    par[i] = i;
    rank[i] = 0;
  }
}

// 木の根を求める
int UnionFind::find(int x) {
  if (par[x] == x) {
    return x;
  } else {
    return par[x] = find(par[x]);
  }
}
// 位数の大きい木に統合する
void UnionFind::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]++;
    }
  }
}

// 同じ根を持つならtrueを返す
bool UnionFind::same(int x, int y) { return find(x) == find(y); }

struct edge {
  int from, to, cost;
};

struct point {
  ll x, y;
  int no;
};

bool comp(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }

bool pcomp1(const point &p1, const point &p2) { return p1.x < p2.x; }

bool pcomp2(const point &p1, const point &p2) { return p1.y < p2.y; }

edge es[MAX];
point p[MAX];

int V, E;

int kruskal() {
  sort(es, es + E, comp);
  UnionFind *tree = new UnionFind(V);
  int res = 0;
  for (int i = 0; i < E; i++) {
    edge e = es[i];
    if (!tree->same(e.from, e.to)) {
      tree->unite(e.from, e.to);
      res += e.cost;
    }
  }
  return res;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(20);

  int N;
  cin >> N;

  V = N;
  E = 2 * N - 2;

  rep(i, N) {
    cin >> p[i].x >> p[i].y;
    p[i].no = i;
  }

  sort(p, p + N, pcomp1);

  rep(i, N - 1) {
    es[i].cost = min(abs(p[i].x - p[i + 1].x), abs(p[i].y - p[i + 1].y));
    es[i].from = p[i].no;
    es[i].to = p[i + 1].no;
  }

  sort(p, p + N, pcomp2);

  for (int i = 0; i < N - 1; i++) {
    int j = i + N - 1;
    es[j].cost = min(abs(p[i].x - p[i + 1].x), abs(p[i].y - p[i + 1].y));
    es[j].from = p[i].no;
    es[j].to = p[i + 1].no;
  }

  cout << kruskal() << endl;

  return 0;
}

// cout << setprecision(13);
// next_permutation();
//__gcd();
// reverse();
// set ,tuple ,pair;
// bitset
// vector.find