Problem p03682 (C++)

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

using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
#define a first
#define b second
#define sz(x) (ll)((x).size())
#define pb push_back
#define mp make_pair
#define bg begin()
#define ed end()
#define all(x) (x).bg, (x).ed
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep1(i, n) for (ll i = 1; i <= (n); i++)
#define rrep1(i, n) for (ll i = (n); i >= 1; i--)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)

struct UnionFind {
  vector<ll> par, siz;

  UnionFind(ll N) : par(N + 1), siz(N + 1, 1) {
    rep1(i, N) par[i] = i; // 親を自分自身として初期化
  }

  ll root(ll x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = root(par[x]);
    }
  }
  void unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;

    if (siz[x] < siz[y])
      swap(x, y);

    siz[x] += siz[y];
    par[y] = x;
  }
  bool same(ll x, ll y) { return root(x) == root(y); }
  ll size(ll x) { return siz[root(x)]; }
};

// 頂点a, bをつなぐコストcostの（無向）辺
struct edge {
  ll from, to, cost;

  // コストの大小で順序定義
  bool operator<(const edge &o) const { return cost < o.cost; }
};

// 頂点数と辺集合の組として定義したグラフ
struct graph {
  ll n;            // 頂点数
  vector<edge> es; // 辺集合

  graph(ll N) { n = N; }

  void add_edge(ll from, ll to, ll cost) {
    edge e;
    e.from = from;
    e.to = to;
    e.cost = cost;
    es.pb(e);
  }

  // クラスカル法で無向最小全域木のコストの和を計算する
  // グラフが非連結のときは最小全域森のコストの和となる
  ll kruskal() {
    // コストが小さい順にソート
    sort(all(es));

    UnionFind uf(n);
    ll res = 0;

    rep(i, sz(es)) {
      edge &e = es[i];
      if (!uf.same(e.from, e.to)) {
        // 辺を追加しても閉路ができないなら、その辺を採用する
        res += e.cost;
        uf.unite(e.from, e.to);
      }
    }

    return res;
  }
};

int main() {
  ll N;
  cin >> N;
  graph g(N); // N頂点用意

  vector<ll> x(N + 1);
  vector<ll> y(N + 1);
  rep1(i, N) cin >> x[i] >> y[i];
  rep1(i, N - 1) {
    FOR(j, i + 1, N + 1) {
      g.add_edge(i, j, min(abs(x[i] - x[j]), abs(y[i] - y[j])));
    }
  }

  cout << g.kruskal();
}

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

using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
#define a first
#define b second
#define sz(x) (ll)((x).size())
#define pb push_back
#define mp make_pair
#define bg begin()
#define ed end()
#define all(x) (x).bg, (x).ed
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep1(i, n) for (ll i = 1; i <= (n); i++)
#define rrep1(i, n) for (ll i = (n); i >= 1; i--)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)

struct UnionFind {
  vector<ll> par, siz;

  UnionFind(ll N) : par(N + 1), siz(N + 1, 1) {
    rep1(i, N) par[i] = i; // 親を自分自身として初期化
  }

  ll root(ll x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = root(par[x]);
    }
  }
  void unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;

    if (siz[x] < siz[y])
      swap(x, y);

    siz[x] += siz[y];
    par[y] = x;
  }
  bool same(ll x, ll y) { return root(x) == root(y); }
  ll size(ll x) { return siz[root(x)]; }
};

// 頂点a, bをつなぐコストcostの（無向）辺
struct edge {
  ll from, to, cost;

  // コストの大小で順序定義
  bool operator<(const edge &o) const { return cost < o.cost; }
};

// 頂点数と辺集合の組として定義したグラフ
struct graph {
  ll n;            // 頂点数
  vector<edge> es; // 辺集合

  graph(ll N) { n = N; }

  void add_edge(ll from, ll to, ll cost) {
    edge e;
    e.from = from;
    e.to = to;
    e.cost = cost;
    es.pb(e);
  }

  // クラスカル法で無向最小全域木のコストの和を計算する
  // グラフが非連結のときは最小全域森のコストの和となる
  ll kruskal() {
    // コストが小さい順にソート
    sort(all(es));

    UnionFind uf(n);
    ll res = 0;

    rep(i, sz(es)) {
      edge &e = es[i];
      if (!uf.same(e.from, e.to)) {
        // 辺を追加しても閉路ができないなら、その辺を採用する
        res += e.cost;
        uf.unite(e.from, e.to);
      }
    }

    return res;
  }
};

int main() {
  ll N;
  cin >> N;
  graph g(N); // N頂点用意

  vector<P> x(N); // x,i-1
  vector<P> y(N); // y,i-1
  vector<P> p(N); // x,y
  rep(i, N) {
    ll X, Y;
    cin >> X >> Y;
    p[i] = P(X, Y);
    x[i] = P(X, i);
    y[i] = P(Y, i);
  }
  sort(all(x));
  sort(all(y));

  rep(i, N - 1) {
    g.add_edge(x[i].b, x[i + 1].b,
               min(abs(p[x[i].b].a - p[x[i + 1].b].a),
                   abs(p[x[i].b].b - p[x[i + 1].b].b)));
    g.add_edge(y[i].b, y[i + 1].b,
               min(abs(p[y[i].b].a - p[y[i + 1].b].a),
                   abs(p[y[i].b].b - p[y[i + 1].b].b)));
  }

  cout << g.kruskal();
}