Problem p02364 (C++) — buggy submission, verdict: Runtime Error

#include <cassert>
#include <iostream>
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME
#define pr(...)                                                                \\
  std::cerr << GET_MACRO(__VA_ARGS__, pr8, pr7, pr6, pr5, pr4, pr3, pr2,       \\
                         pr1)(__VA_ARGS__)                                     \\
            << std::endl
#define pr1(a) (#a) << "=" << (a) << " "
#define pr2(a, b) pr1(a) << pr1(b)
#define pr3(a, b, c) pr1(a) << pr2(b, c)
#define pr4(a, b, c, d) pr1(a) << pr3(b, c, d)
#define pr5(a, b, c, d, e) pr1(a) << pr4(b, c, d, e)
#define pr6(a, b, c, d, e, f) pr1(a) << pr5(b, c, d, e, f)
#define pr7(a, b, c, d, e, f, g) pr1(a) << pr6(b, c, d, e, f, g)
#define pr8(a, b, c, d, e, f, g, h) pr1(a) << pr7(b, c, d, e, f, g, h)
#define prArr(a)                                                               \\
  {                                                                            \\
    cerr << (#a) << "={";                                                      \\
    int i = 0;                                                                 \\
    for (auto t : (a))                                                         \\
      cerr << (i++ ? ", " : "") << t;                                          \\
    cerr << "}" << endl;                                                       \\
  }

template <typename T> class Deque {
public:
  T *val;
  int sz;
  int length;
  int head, tail;

  Deque() { sz = 0, length = 0, val = new T[0]; }
  Deque(int size, T init = T()) {
    length = 1;
    while (length < size)
      length *= 2;
    val = new T[length];
    sz = size;
    head = 0;
    tail = 0;
    for (int i = 0; i < size; i++)
      val[tail++] = init;
  }

  Deque(const Deque &t) {
    sz = t.size();
    length = 1;
    while (length < sz)
      length *= 2;
    val = new T[length];
    head = 0;
    tail = 0;
    for (int i = 0; i < sz; i++)
      val[tail++] = t[i];
  }

  ~Deque() { delete[] val; }

  Deque<T> operator=(const Deque<T> t) {
    delete[] val;
    sz = t.size();
    length = 1;
    while (length < sz)
      length *= 2;
    val = new T[length];
    head = 0;
    tail = 0;
    for (int i = 0; i < sz; i++)
      val[tail++] = t[i];
    return t;
  };

  T &operator[](int i) {
    assert(0 <= i && i < sz);
    return head + i < length ? val[head + i] : val[head + i - length];
  }
  T &operator[](int i) const {
    assert(0 <= i && i < sz);
    return head + i < length ? val[head + i] : val[head + i - length];
  }

  bool operator==(const Deque<T> &a) const {
    if (size() != a.size())
      return 0;
    for (int i = 0; i < size(); i++)
      if (!((*this)[i] == a[i]))
        return 0;
    return 1;
  }

  T &front() { return val[head]; }
  T &back() { return val[(head + sz - 1) % length]; }

  int size() const { return sz; }
  int empty() const { return sz == 0; }

  void resize(int n, T v = T()) {
    while (n < size())
      pop_back();
    while (n > size())
      push_back_fast(v);
  }

  void increaseMemory() {
    int length_ = length;
    length = length * 2;
    if (length == 0)
      length = 1;
    T *val2 = new T[length];
    for (int i = 0; i < sz; i++)
      val2[i] = val[(head + i) % length_];
    head = 0;
    tail = sz;
    delete[] val;
    val = val2;
  };

  void push_back(T v) {
    if (sz == length)
      increaseMemory();
    sz++;
    val[tail++] = v;
    if (tail == length)
      tail = 0;
  }

  void push_back_fast(T &v) {
    if (sz == length)
      increaseMemory();
    sz++;
    val[tail++] = v;
    if (tail == length)
      tail = 0;
  }

  void push_front(int v) {
    if (sz == length)
      increaseMemory();
    sz++;
    head--;
    if (head == -1)
      head = length - 1;
    val[head] = v;
  }

  void pop_back() {
    assert(sz > 0);
    sz--;
    tail--;
    if (tail == -1)
      tail = length - 1;
  }

  void pop_front() {
    assert(sz > 0);
    sz--;
    head++;
    if (head == length)
      head = 0;
  }

  friend std::ostream &operator<<(std::ostream &os, const Deque<T> a) {
    os << "[";
    for (int i = 0; i < a.size(); i++) {
      if (i)
        os << " ";
      os << a[i];
    }
    os << "]";
    return os;
  }
};

template <typename T> using vector = Deque<T>;

class UF {
public:
  int V;
  vector<int> par, rnk, sz;
  UF() {}
  UF(int V) : V(V), par(V), rnk(V, 0), sz(V, 1) {
    for (int i = 0; i < V; i++)
      par[i] = i;
  }

  int find(int x) {
    assert(x < V);
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }

  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return;
    if (rnk[x] < rnk[y])
      par[x] = y, sz[y] += sz[x];
    else {
      par[y] = x;
      sz[x] += sz[y];
      if (rnk[x] == rnk[y])
        rnk[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int size(int x) { return sz[find(x)]; }
};

template <class T, class D> void sort(D &A, int n) {
  auto tmp = new T[n];

  auto dfs = [&](int l, int r, auto f) {
    if (l + 1 >= r)
      return;
    int m = (l + r) / 2;
    f(l, m, f);
    f(m, r, f);

    int idx = 0;
    int i = l;
    int j = m;
    while (i < m || j < r) {
      if (i >= m)
        tmp[idx] = A[j++];
      else if (j >= r)
        tmp[idx] = A[i++];
      else if (A[i] < A[j])
        tmp[idx] = A[i++];
      else
        tmp[idx] = A[j++];
      idx++;
    }
    for (int i = 0; i < r - l; i++)
      A[l + i] = tmp[i];
  };

  dfs(0, n, dfs);
  delete[] tmp;
}

struct data {
  int a, b, c;
  data() {}
  data(int a, int b, int c) : a(a), b(b), c(c) {}
  bool operator<(data d) const { return c < d.c; }
};

long long kruskal(int N, vector<data> edge) {
  UF uf(N);
  int M = edge.size();
  sort<data>(edge, M);
  long long res = 0;
  for (int i = 0; i < M; i++) {
    auto e = edge[i];
    if (uf.same(e.a, e.b))
      continue;
    uf.unite(e.a, e.b);
    res += e.c;
  }
  return res;
}

signed main() {

  int N, M;
  std::cin >> N >> M;

  vector<data> edge(M);
  for (int i = 0; i < M; i++) {
    int a, b, c;
    std::cin >> a >> b >> c;
    edge[i] = data(a, b, c);
  }
  long long ans = kruskal(N, edge);
  std::cout << ans << std::endl;

  return 0;
}


Error: 0

Fixed submission:

#include <cassert>
#include <iostream>
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME
#define pr(...)                                                                \\
  std::cerr << GET_MACRO(__VA_ARGS__, pr8, pr7, pr6, pr5, pr4, pr3, pr2,       \\
                         pr1)(__VA_ARGS__)                                     \\
            << std::endl
#define pr1(a) (#a) << "=" << (a) << " "
#define pr2(a, b) pr1(a) << pr1(b)
#define pr3(a, b, c) pr1(a) << pr2(b, c)
#define pr4(a, b, c, d) pr1(a) << pr3(b, c, d)
#define pr5(a, b, c, d, e) pr1(a) << pr4(b, c, d, e)
#define pr6(a, b, c, d, e, f) pr1(a) << pr5(b, c, d, e, f)
#define pr7(a, b, c, d, e, f, g) pr1(a) << pr6(b, c, d, e, f, g)
#define pr8(a, b, c, d, e, f, g, h) pr1(a) << pr7(b, c, d, e, f, g, h)
#define prArr(a)                                                               \\
  {                                                                            \\
    cerr << (#a) << "={";                                                      \\
    int i = 0;                                                                 \\
    for (auto t : (a))                                                         \\
      cerr << (i++ ? ", " : "") << t;                                          \\
    cerr << "}" << endl;                                                       \\
  }

template <typename T> class Deque {
public:
  T *val;
  int sz;
  int length;
  int head, tail;

  Deque() { sz = 0, length = 0, val = new T[0]; }
  Deque(int size, T init = T()) {
    length = 1;
    while (length < size)
      length *= 2;
    val = new T[length];
    sz = size;
    head = 0;
    tail = 0;
    for (int i = 0; i < size; i++)
      val[tail++] = init;
  }

  Deque(const Deque &t) {
    sz = t.size();
    length = 1;
    while (length < sz)
      length *= 2;
    val = new T[length];
    head = 0;
    tail = 0;
    for (int i = 0; i < sz; i++)
      val[tail++] = t[i];
  }

  ~Deque() { delete[] val; }

  Deque<T> operator=(const Deque<T> t) {
    delete[] val;
    sz = t.size();
    length = 1;
    while (length < sz)
      length *= 2;
    val = new T[length];
    head = 0;
    tail = 0;
    for (int i = 0; i < sz; i++)
      val[tail++] = t[i];
    return t;
  };

  T &operator[](int i) {
    assert(0 <= i && i < sz);
    return head + i < length ? val[head + i] : val[head + i - length];
  }
  T &operator[](int i) const {
    assert(0 <= i && i < sz);
    return head + i < length ? val[head + i] : val[head + i - length];
  }

  bool operator==(const Deque<T> &a) const {
    if (size() != a.size())
      return 0;
    for (int i = 0; i < size(); i++)
      if (!((*this)[i] == a[i]))
        return 0;
    return 1;
  }

  T &front() { return val[head]; }
  T &back() { return val[(head + sz - 1) % length]; }

  int size() const { return sz; }
  int empty() const { return sz == 0; }

  void resize(int n, T v = T()) {
    while (n < size())
      pop_back();
    while (n > size())
      push_back_fast(v);
  }

  void increaseMemory() {
    int length_ = length;
    length = length * 2;
    if (length == 0)
      length = 1;
    T *val2 = new T[length];
    for (int i = 0; i < sz; i++)
      val2[i] = val[(head + i) % length_];
    head = 0;
    tail = sz;
    delete[] val;
    val = val2;
  };

  void push_back(T v) {
    if (sz == length)
      increaseMemory();
    sz++;
    val[tail++] = v;
    if (tail == length)
      tail = 0;
  }

  void push_back_fast(T &v) {
    if (sz == length)
      increaseMemory();
    sz++;
    val[tail++] = v;
    if (tail == length)
      tail = 0;
  }

  void push_front(int v) {
    if (sz == length)
      increaseMemory();
    sz++;
    head--;
    if (head == -1)
      head = length - 1;
    val[head] = v;
  }

  void pop_back() {
    assert(sz > 0);
    sz--;
    tail--;
    if (tail == -1)
      tail = length - 1;
  }

  void pop_front() {
    assert(sz > 0);
    sz--;
    head++;
    if (head == length)
      head = 0;
  }

  friend std::ostream &operator<<(std::ostream &os, const Deque<T> a) {
    os << "[";
    for (int i = 0; i < a.size(); i++) {
      if (i)
        os << " ";
      os << a[i];
    }
    os << "]";
    return os;
  }
};

template <typename T> using vector = Deque<T>;

class UF {
public:
  int V;
  vector<int> par, rnk, sz;
  UF() {}
  UF(int V) : V(V), par(V), rnk(V, 0), sz(V, 1) {
    for (int i = 0; i < V; i++)
      par[i] = i;
  }

  int find(int x) {
    assert(x < V);
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }

  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return;
    if (rnk[x] < rnk[y])
      par[x] = y, sz[y] += sz[x];
    else {
      par[y] = x;
      sz[x] += sz[y];
      if (rnk[x] == rnk[y])
        rnk[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int size(int x) { return sz[find(x)]; }
};

template <class T, class D> void sort(D &A, int n) {
  auto tmp = new T[n];

  auto dfs = [&](int l, int r, auto f) {
    if (l + 1 == r)
      return;
    int m = (l + r) / 2;
    f(l, m, f);
    f(m, r, f);

    int idx = 0;
    int i = l;
    int j = m;
    while (i < m || j < r) {
      if (i >= m)
        tmp[idx] = A[j++];
      else if (j >= r)
        tmp[idx] = A[i++];
      else if (A[i] < A[j])
        tmp[idx] = A[i++];
      else
        tmp[idx] = A[j++];
      idx++;
    }
    for (int i = 0; i < r - l; i++)
      A[l + i] = tmp[i];
  };

  dfs(0, n, dfs);
  delete[] tmp;
}

struct data {
  int a, b, c;
  data() {}
  data(int a, int b, int c) : a(a), b(b), c(c) {}
  bool operator<(data d) const { return c < d.c; }
};

long long kruskal(int N, vector<data> edge) {
  UF uf(N);
  int M = edge.size();
  sort<data>(edge, M);
  long long res = 0;
  for (int i = 0; i < M; i++) {
    auto e = edge[i];
    if (uf.same(e.a, e.b))
      continue;
    uf.unite(e.a, e.b);
    res += e.c;
  }
  return res;
}

signed main() {

  int N, M;
  std::cin >> N >> M;

  vector<data> edge(M);
  for (int i = 0; i < M; i++) {
    int a, b, c;
    std::cin >> a >> b >> c;
    edge[i] = data(a, b, c);
  }

  long long ans = kruskal(N, edge);
  std::cout << ans << std::endl;

  return 0;
}