Problem p03682 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<ll, P> PP;
int N;
ll X, Y;
ll p[100010] = {0}, r[100010] = {0};

void init(ll N) {
  for (int i = 1; i <= N; ++i)
    p[i] = i;
}

int root(ll a) {
  if (p[a] == a)
    return a;
  return (p[a] = root(p[a]));
}

bool is_same_set(ll a, ll b) { return root(a) == root(b); }

void unite(ll a, ll b) {
  a = root(a);
  b = root(b);
  if (a == b)
    return;
  if (r[a] < r[b]) {
    p[a] = b;
  } else {
    p[b] = a;
    if (r[a] == r[b])
      r[a]++;
  }
}

struct edge {
  ll u, v, cost;
};

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

edge es[300000];

int main() {
  cin >> N;
  vector<PP> v(N + 1), u(N + 1);
  for (int i = 1; i <= N; i++) {
    cin >> X >> Y;
    v[i] = PP(X, P(Y, i));
    u[i] = PP(Y, P(X, i));
  }
  ll ans = 0;
  sort(v.begin() + 1, v.end());
  sort(u.begin() + 1, u.end());
  int j = 0;
  for (int i = 1; i < N; i++) {
    es[j].u = v[i].second.second;
    es[j].v = v[i + 1].second.second;
    es[j].cost = min(abs(v[i].first - v[i + 1].first),
                     abs(v[i].second.first - v[i + 1].second.first));
    j++;
    es[j].u = v[i + 1].second.second;
    es[j].v = v[i].second.second;
    es[j].cost = min(abs(v[i].first - v[i + 1].first),
                     abs(v[i].second.first - v[i + 1].second.first));
    j++;
    es[j].u = u[i].second.second;
    es[j].v = u[i + 1].second.second;
    es[j].cost = min(abs(u[i].first - u[i + 1].first),
                     abs(u[i].second.first - u[i + 1].second.first));
    j++;
    es[j].u = u[i + 1].second.second;
    es[j].v = u[i].second.second;
    es[j].cost = min(abs(u[i].first - u[i + 1].first),
                     abs(u[i].second.first - u[i + 1].second.first));
    j++;
  }
  sort(es, es + j - 1, comp);
  init(N);
  for (int i = 0; i < j; i++) {
    edge e = es[i];
    if (!is_same_set(e.u, e.v)) {
      unite(e.u, e.v);
      ans += e.cost;
      //			cout << e.u << " " << e.v << " " << e.cost <<
      //endl;
    }
  }
  cout << ans << endl;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<ll, P> PP;
int N;
ll X, Y;
ll p[100010] = {0}, r[100010] = {0};

void init(ll N) {
  for (int i = 1; i <= N; ++i)
    p[i] = i;
}

int root(ll a) {
  if (p[a] == a)
    return a;
  return (p[a] = root(p[a]));
}

bool is_same_set(ll a, ll b) { return root(a) == root(b); }

void unite(ll a, ll b) {
  a = root(a);
  b = root(b);
  if (a == b)
    return;
  if (r[a] < r[b]) {
    p[a] = b;
  } else {
    p[b] = a;
    if (r[a] == r[b])
      r[a]++;
  }
}

struct edge {
  ll u, v, cost;
};

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

edge es[400010];

int main() {
  cin >> N;
  vector<PP> v(N + 1), u(N + 1);
  for (int i = 1; i <= N; i++) {
    cin >> X >> Y;
    v[i] = PP(X, P(Y, i));
    u[i] = PP(Y, P(X, i));
  }
  ll ans = 0;
  sort(v.begin() + 1, v.end());
  sort(u.begin() + 1, u.end());
  int j = 0;
  for (int i = 1; i < N; i++) {
    es[j].u = v[i].second.second;
    es[j].v = v[i + 1].second.second;
    es[j].cost = min(abs(v[i].first - v[i + 1].first),
                     abs(v[i].second.first - v[i + 1].second.first));
    j++;
    es[j].u = v[i + 1].second.second;
    es[j].v = v[i].second.second;
    es[j].cost = min(abs(v[i].first - v[i + 1].first),
                     abs(v[i].second.first - v[i + 1].second.first));
    j++;
    es[j].u = u[i].second.second;
    es[j].v = u[i + 1].second.second;
    es[j].cost = min(abs(u[i].first - u[i + 1].first),
                     abs(u[i].second.first - u[i + 1].second.first));
    j++;
    es[j].u = u[i + 1].second.second;
    es[j].v = u[i].second.second;
    es[j].cost = min(abs(u[i].first - u[i + 1].first),
                     abs(u[i].second.first - u[i + 1].second.first));
    j++;
  }
  sort(es, es + j - 1, comp);
  init(N);
  for (int i = 0; i < j; i++) {
    edge e = es[i];
    if (!is_same_set(e.u, e.v)) {
      unite(e.u, e.v);
      ans += e.cost;
      //			cout << e.u << " " << e.v << " " << e.cost <<
      //endl;
    }
  }
  cout << ans << endl;
}