Problem p03682 (C++)

Buggy submission (status: Runtime Error):
// {{{
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define FOR(i, a, b)                                                           \
  for (size_t i = static_cast<size_t>(a); i < static_cast<size_t>(b); i++)
#define FORR(i, a, b)                                                          \
  for (size_t i = static_cast<size_t>(a); i >= static_cast<size_t>(b); i--)
#define REP(i, n) for (size_t i = 0; i < static_cast<size_t>(n); i++)
#define REPR(i, n) for (size_t i = static_cast<size_t>(n); i >= 0; i--)
#define ALL(x) (x).begin(), (x).end()

typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef pair<int, P> IP;
typedef pair<ll, LP> LLP;

int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};

constexpr int INF = 100000000;
constexpr ll LINF = 10000000000000000ll;
constexpr int MOD = static_cast<int>(1e9 + 7);
constexpr double EPS = 1e-9;
// }}}

class UnionFind {
  vector<size_t> m_parents;
  vector<ll> m_ranks;

public:
  UnionFind(size_t n) {
    m_parents.resize(n);
    m_ranks.resize(n);
    for (size_t i = 0; i < n; i++) {
      m_parents[i] = i;
      m_ranks[i] = 0;
    }
  }

  size_t root(size_t x) {
    if (m_parents[x] == x)
      return x;
    size_t r = root(m_parents[x]);
    m_parents[x] = r;
    return r;
  }

  bool isSame(size_t x, size_t y) { return root(x) == root(y); }

  void unite(size_t x, size_t y) {
    size_t rx = root(x);
    size_t ry = root(y);
    if (rx != ry) {
      if (m_ranks[rx] < m_ranks[ry])
        swap(rx, ry);
      if (m_ranks[rx] == m_ranks[ry])
        m_ranks[rx]++;
      m_parents[ry] = rx;
    }
  }
};

ll V, E;
LLP vs[100010];
struct edge {
  ll u, v, cost;
  edge() : u(0), v(0), cost(0){};
  edge(ll u_, ll v_) : u(u_), v(v_) {
    cost = min(abs(vs[u].se.fi - vs[v].se.fi), abs(vs[u].se.se - vs[v].se.se));
    // cout << "[" << u << ", " << v << "] " << cost << endl;
  };
};
edge es[100010];
bool comp(const edge &lhs, const edge &rhs) { return lhs.cost < rhs.cost; }
bool xcomp(const LLP &lhs, const LLP &rhs) { return lhs.se.fi < rhs.se.fi; }

bool ycomp(const LLP &lhs, const LLP &rhs) { return lhs.se.se < rhs.se.se; }

ll kruskal() {
  sort(es, es + E, comp);
  UnionFind uf(V);
  ll ret = 0;
  REP(i, E) {
    edge e = es[i];
    // cout << "(" << e.cost << ")" << endl;
    if (!uf.isSame(e.u, e.v)) {
      uf.unite(e.u, e.v);
      // cout << e.cost << endl;
      ret += e.cost;
    }
  }
  return ret;
}

void init() {}

void solve() {
  vector<LLP> xvs, yvs;
  REP(i, V) {
    xvs.pb(vs[i]);
    yvs.pb(vs[i]);
  }
  sort(xvs.begin(), xvs.end(), xcomp);
  sort(yvs.begin(), yvs.end(), ycomp);
  E = 4 * (V - 1);
  REP(i, V - 1) {
    es[4 * i] = edge(xvs[i].fi, xvs[i + 1].fi);
    es[4 * i + 1] = edge(xvs[i + 1].fi, xvs[i].fi);
    es[4 * i + 2] = edge(yvs[i].fi, yvs[i + 1].fi);
    es[4 * i + 3] = edge(yvs[i + 1].fi, yvs[i].fi);
  }
  cout << kruskal() << endl;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> V;
  REP(i, V) {
    ll x, y;
    cin >> x >> y;
    vs[i] = LLP(i, LP(x, y));
  }
  solve();
  return 0;
}

// vim:set foldmethod=marker:


Fixed submission:
// {{{
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define FOR(i, a, b)                                                           \
  for (size_t i = static_cast<size_t>(a); i < static_cast<size_t>(b); i++)
#define FORR(i, a, b)                                                          \
  for (size_t i = static_cast<size_t>(a); i >= static_cast<size_t>(b); i--)
#define REP(i, n) for (size_t i = 0; i < static_cast<size_t>(n); i++)
#define REPR(i, n) for (size_t i = static_cast<size_t>(n); i >= 0; i--)
#define ALL(x) (x).begin(), (x).end()

typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef pair<int, P> IP;
typedef pair<ll, LP> LLP;

int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};

constexpr int INF = 100000000;
constexpr ll LINF = 10000000000000000ll;
constexpr int MOD = static_cast<int>(1e9 + 7);
constexpr double EPS = 1e-9;
// }}}

class UnionFind {
  vector<size_t> m_parents;
  vector<ll> m_ranks;

public:
  UnionFind(size_t n) {
    m_parents.resize(n);
    m_ranks.resize(n);
    for (size_t i = 0; i < n; i++) {
      m_parents[i] = i;
      m_ranks[i] = 0;
    }
  }

  size_t root(size_t x) {
    if (m_parents[x] == x)
      return x;
    size_t r = root(m_parents[x]);
    m_parents[x] = r;
    return r;
  }

  bool isSame(size_t x, size_t y) { return root(x) == root(y); }

  void unite(size_t x, size_t y) {
    size_t rx = root(x);
    size_t ry = root(y);
    if (rx != ry) {
      if (m_ranks[rx] < m_ranks[ry])
        swap(rx, ry);
      if (m_ranks[rx] == m_ranks[ry])
        m_ranks[rx]++;
      m_parents[ry] = rx;
    }
  }
};

ll V, E;
LLP vs[100010];
struct edge {
  ll u, v, cost;
  edge() : u(0), v(0), cost(0){};
  edge(ll u_, ll v_) : u(u_), v(v_) {
    cost = min(abs(vs[u].se.fi - vs[v].se.fi), abs(vs[u].se.se - vs[v].se.se));
    // cout << "[" << u << ", " << v << "] " << cost << endl;
  };
};
edge es[400040];
bool comp(const edge &lhs, const edge &rhs) { return lhs.cost < rhs.cost; }
bool xcomp(const LLP &lhs, const LLP &rhs) { return lhs.se.fi < rhs.se.fi; }

bool ycomp(const LLP &lhs, const LLP &rhs) { return lhs.se.se < rhs.se.se; }

ll kruskal() {
  sort(es, es + E, comp);
  UnionFind uf(V);
  ll ret = 0;
  REP(i, E) {
    edge e = es[i];
    // cout << "(" << e.cost << ")" << endl;
    if (!uf.isSame(e.u, e.v)) {
      uf.unite(e.u, e.v);
      // cout << e.cost << endl;
      ret += e.cost;
    }
  }
  return ret;
}

void init() {}

void solve() {
  vector<LLP> xvs, yvs;
  REP(i, V) {
    xvs.pb(vs[i]);
    yvs.pb(vs[i]);
  }
  sort(xvs.begin(), xvs.end(), xcomp);
  sort(yvs.begin(), yvs.end(), ycomp);
  E = 4 * (V - 1);
  REP(i, V - 1) {
    es[4 * i] = edge(xvs[i].fi, xvs[i + 1].fi);
    es[4 * i + 1] = edge(xvs[i + 1].fi, xvs[i].fi);
    es[4 * i + 2] = edge(yvs[i].fi, yvs[i + 1].fi);
    es[4 * i + 3] = edge(yvs[i + 1].fi, yvs[i].fi);
  }
  cout << kruskal() << endl;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> V;
  REP(i, V) {
    ll x, y;
    cin >> x >> y;
    vs[i] = LLP(i, LP(x, y));
  }
  solve();
  return 0;
}

// vim:set foldmethod=marker: