Problem p00600 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)(n); (i)++)
#define foreach(itr, c)                                                        \
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)
inline int in() {
  int x;
  scanf("%d", &x);
  return x;
}

//----------union find------------------- begin
namespace UF {
#define MAX_N 1000
int par[MAX_N], rank[MAX_N];

void init(int n) {
  int i;
  rep(i, n) {
    par[i] = i;
    rank[i] = 0;
  }
}

int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}

void 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]++;
  }
}

bool same(int x, int y) { return find(x) == find(y); }
} // namespace UF
//--------------------------------------- end

struct Edge {
  int from, to, cost;

  Edge(int from_, int to_, int cost_) {
    from = from_;
    to = to_;
    cost = cost_;
  }
  bool operator<(const Edge &a) const { return cost < a.cost; }
};

int main() {
  int i, j, k;
  int s, d;

  while (scanf("%d %d", &s, &d)) {
    if (s == 0 && d == 0)
      break;
    vector<Edge> edges;

    rep(i, s) rep(j, d) {
      int t = in();
      if (t == 0)
        continue;
      edges.push_back(Edge(i, s + j, t));
    }
    rep(i, d - 1) for (j = i + 1; j < d; j++) {
      int t = in();
      if (t == 0)
        continue;
      edges.push_back(Edge(s + i, s + j, t));
    }

    //-------------begin here-----------
    sort(edges.begin(), edges.end());

    int ans = 0;
    int n = edges.size();
    //    rep(i,n) cout << edges[i].cost << endl;
    UF::init(n);
    for (i = 1; i < s; i++)
      UF::unite(i, 0);
    rep(i, n) {
      if (UF::same(edges[i].from, edges[i].to))
        continue;
      ans += edges[i].cost;
      UF::unite(edges[i].from, edges[i].to);
    }

    printf("%d\n", ans);
  }

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)(n); (i)++)
#define foreach(itr, c)                                                        \
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)
inline int in() {
  int x;
  scanf("%d", &x);
  return x;
}

//----------union find------------------- begin
namespace UF {
#define MAX_N 10000
int par[MAX_N], rank[MAX_N];

void init(int n) {
  int i;
  rep(i, n) {
    par[i] = i;
    rank[i] = 0;
  }
}

int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}

void 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]++;
  }
}

bool same(int x, int y) { return find(x) == find(y); }
} // namespace UF
//--------------------------------------- end

struct Edge {
  int from, to, cost;

  Edge(int from_, int to_, int cost_) {
    from = from_;
    to = to_;
    cost = cost_;
  }
  bool operator<(const Edge &a) const { return cost < a.cost; }
};

int main() {
  int i, j, k;
  int s, d;

  while (scanf("%d %d", &s, &d)) {
    if (s == 0 && d == 0)
      break;
    vector<Edge> edges;

    rep(i, s) rep(j, d) {
      int t = in();
      if (t == 0)
        continue;
      edges.push_back(Edge(i, s + j, t));
    }
    rep(i, d - 1) for (j = i + 1; j < d; j++) {
      int t = in();
      if (t == 0)
        continue;
      edges.push_back(Edge(s + i, s + j, t));
    }

    //-------------begin here-----------
    sort(edges.begin(), edges.end());

    int ans = 0;
    int n = edges.size();
    //    rep(i,n) cout << edges[i].cost << endl;
    UF::init(n);
    for (i = 1; i < s; i++)
      UF::unite(i, 0);
    rep(i, n) {
      if (UF::same(edges[i].from, edges[i].to))
        continue;
      ans += edges[i].cost;
      UF::unite(edges[i].from, edges[i].to);
    }

    printf("%d\n", ans);
  }

  return 0;
}