Problem p03682 (C++)

Buggy submission (status: Runtime Error):
// 适用于稀疏图
// 复杂度 mlog(n)

#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int n, m;
const int N = 1e5 + 7;
int father[N];
// 边的信息
struct Edge {
  ll a, b, v;
  /*
  bool operator< (const Edge &W) const
  {
      return v < W.v;
  }
  */
};
Edge edge[N];
// 并查集——寻找当前集合的代表元素
int find(int x) {
  if (father[x] != x)
    father[x] = find(father[x]);
  return father[x];
}

// 所有边存储在 Edge edges[M];
// 函数返回最小生成树中所有边的总长度
int cmp3(Edge a, Edge b) { return a.v < b.v; }
int Kruskal() {
  int num = 0;
  long long res = 0;
  // 初始化并查集代表元素
  for (int i = 1; i <= n; i++)
    father[i] = i;
  sort(edge + 1, edge + 1 + m, cmp3);
  for (int i = 1; i <= m; i++) {
    int a = edge[i].a, b = edge[i].b;
    if (find(a) != find(b)) {
      father[find(a)] = find(b);
      num++;
      res += edge[i].v;
    }
    if (num == n - 1)
      break;
  }
  return res;
}

struct node {
  ll x, y, id;
} nd[N];
int cmp1(node a, node b) { return a.x < b.x; }
int cmp2(node a, node b) { return a.y < b.y; }

int main() {
  int t;
  cin >> t;
  for (int i = 1; i <= t; i++) {
    cin >> nd[i].x >> nd[i].y;
    nd[i].id = i;
  }

  sort(nd + 1, nd + 1 + t, cmp1);
  int tot = 0;
  for (int i = 1; i < t; i++) {
    edge[++tot].a = nd[i + 1].id;
    edge[tot].b = nd[i].id;
    edge[tot].v = nd[i + 1].x - nd[i].x;
  }

  sort(nd + 1, nd + 1 + t, cmp2);
  for (int i = 1; i < t; i++) {
    edge[++tot].a = nd[i + 1].id;
    edge[tot].b = nd[i].id;
    edge[tot].v = nd[i + 1].y - nd[i].y;
  }
  m = tot;
  n = t;
  // cout << "m " << m << endl;
  cout << Kruskal() << endl;
  return 0;
}


Fixed submission:
// 适用于稀疏图
// 复杂度 mlog(n)

#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int n, m;
const int N = 1e5 + 7;
int father[N];
// 边的信息
struct Edge {
  ll a, b, v;
  /*
  bool operator< (const Edge &W) const
  {
      return v < W.v;
  }
  */
};
Edge edge[N * 2];
// 并查集——寻找当前集合的代表元素
int find(int x) {
  if (father[x] != x)
    father[x] = find(father[x]);
  return father[x];
}

// 所有边存储在 Edge edges[M];
// 函数返回最小生成树中所有边的总长度
int cmp3(Edge a, Edge b) { return a.v < b.v; }
int Kruskal() {
  int num = 0;
  long long res = 0;
  // 初始化并查集代表元素
  for (int i = 1; i <= n; i++)
    father[i] = i;
  sort(edge + 1, edge + 1 + m, cmp3);
  for (int i = 1; i <= m; i++) {
    int a = edge[i].a, b = edge[i].b;
    if (find(a) != find(b)) {
      father[find(a)] = find(b);
      num++;
      res += edge[i].v;
    }
    if (num == n - 1)
      break;
  }
  return res;
}

struct node {
  ll x, y, id;
} nd[N];
int cmp1(node a, node b) { return a.x < b.x; }
int cmp2(node a, node b) { return a.y < b.y; }

int main() {
  int t;
  cin >> t;
  for (int i = 1; i <= t; i++) {
    cin >> nd[i].x >> nd[i].y;
    nd[i].id = i;
  }

  sort(nd + 1, nd + 1 + t, cmp1);
  int tot = 0;
  for (int i = 1; i < t; i++) {
    edge[++tot].a = nd[i + 1].id;
    edge[tot].b = nd[i].id;
    edge[tot].v = nd[i + 1].x - nd[i].x;
  }

  sort(nd + 1, nd + 1 + t, cmp2);
  for (int i = 1; i < t; i++) {
    edge[++tot].a = nd[i + 1].id;
    edge[tot].b = nd[i].id;
    edge[tot].v = nd[i + 1].y - nd[i].y;
  }
  m = tot;
  n = t;
  // cout << "m " << m << endl;
  cout << Kruskal() << endl;
  return 0;
}