Problem p03143 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pi;
typedef pair<double, double> pd;
typedef pair<double, ll> pdl;
#define F first
#define S second
const ll E = 1e18 + 7;
const ll MOD = 1000000007;

vector<pll> uft;

ll parent(ll a) { return uft[a].F == a ? a : uft[a].F = parent(uft[a].F); }

void merge(ll p, ll c) {
  if (parent(p) == parent(c)) {
    return;
  }
  uft[parent(p)].S += uft[parent(c)].S;
  uft[parent(c)].F = parent(p);
}

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> X(n);
  for (auto &I : X) {
    cin >> I;
  }

  uft.resize(n + m);
  for (int i = 0; i < n; i++) {
    uft[i] = {i, X[i]};
  }
  for (int i = 0; i < m; i++) {
    uft[i + n] = {i + n, 0};
  }

  vector<pair<ll, pll>> edge(m);
  for (auto &I : edge) {
    cin >> I.S.F >> I.S.S >> I.F;
    I.S.F--;
    I.S.S--;
  }
  sort(edge.begin(), edge.end());

  vector<pll> children(m, {-1, -1});
  vector<bool> used(m, false);

  for (int i = 0; i < m; i++) {
    if (parent(edge[i].S.F) == parent(edge[i].S.S)) {
      continue;
    }
    used[i] = true;
    if (parent(edge[i].S.F) >= n &&
        uft[parent(edge[i].S.F)].S < edge[parent(edge[i].S.F) - n].F) {
      children[i].F = parent(edge[i].S.F) - n;
    }
    if (parent(edge[i].S.S) >= n &&
        uft[parent(edge[i].S.S)].S < edge[parent(edge[i].S.S) - n].F) {
      children[i].S = parent(edge[i].S.S) - n;
    }
    merge(i + n, edge[i].S.F);
    merge(i + n, edge[i].S.S);
  }

  if (uft[parent(0)].S < edge[parent(0) - n].F) {
    queue<ll> Q;
    Q.push(parent(0) - n);
    while (!Q.empty()) {
      ll w = Q.front();
      Q.pop();
      used[w] = false;
      if (children[w].F != -1) {
        Q.push(children[w].F);
      }
      if (children[w].S != -1) {
        Q.push(children[w].S);
      }
    }
  }

  ll ans = 0;
  for (int i = 0; i < n; i++) {
    uft[i] = {i, X[i]};
  }
  for (int i = 0; i < m; i++) {
    if (used[i]) {
      ans++;
      merge(edge[i].S.F, edge[i].S.S);
    }
  }
  for (int i = 0; i < m; i++) {
    if (!used[i]) {
      if (parent(edge[i].S.F) == parent(edge[i].S.S) &&
          uft[parent(edge[i].S.S)].S >= edge[i].F) {
        ans++;
      }
    }
  }
  cout << m - ans << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pi;
typedef pair<double, double> pd;
typedef pair<double, ll> pdl;
#define F first
#define S second
const ll E = 1e18 + 7;
const ll MOD = 1000000007;

vector<pll> uft;

ll parent(ll a) { return uft[a].F == a ? a : uft[a].F = parent(uft[a].F); }

void merge(ll p, ll c) {
  if (parent(p) == parent(c)) {
    return;
  }
  uft[parent(p)].S += uft[parent(c)].S;
  uft[parent(c)].F = parent(p);
}

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> X(n);
  for (auto &I : X) {
    cin >> I;
  }
  if (n == 1) {
    cout << 0 << endl;
    return 0;
  }

  uft.resize(n + m);
  for (int i = 0; i < n; i++) {
    uft[i] = {i, X[i]};
  }
  for (int i = 0; i < m; i++) {
    uft[i + n] = {i + n, 0};
  }

  vector<pair<ll, pll>> edge(m);
  for (auto &I : edge) {
    cin >> I.S.F >> I.S.S >> I.F;
    I.S.F--;
    I.S.S--;
  }
  sort(edge.begin(), edge.end());

  vector<pll> children(m, {-1, -1});
  vector<bool> used(m, false);

  for (int i = 0; i < m; i++) {
    if (parent(edge[i].S.F) == parent(edge[i].S.S)) {
      continue;
    }
    used[i] = true;
    if (parent(edge[i].S.F) >= n &&
        uft[parent(edge[i].S.F)].S < edge[parent(edge[i].S.F) - n].F) {
      children[i].F = parent(edge[i].S.F) - n;
    }
    if (parent(edge[i].S.S) >= n &&
        uft[parent(edge[i].S.S)].S < edge[parent(edge[i].S.S) - n].F) {
      children[i].S = parent(edge[i].S.S) - n;
    }
    merge(i + n, edge[i].S.F);
    merge(i + n, edge[i].S.S);
  }

  if (uft[parent(0)].S < edge[parent(0) - n].F) {
    queue<ll> Q;
    Q.push(parent(0) - n);
    while (!Q.empty()) {
      ll w = Q.front();
      Q.pop();
      used[w] = false;
      if (children[w].F != -1) {
        Q.push(children[w].F);
      }
      if (children[w].S != -1) {
        Q.push(children[w].S);
      }
    }
  }

  ll ans = 0;
  for (int i = 0; i < n; i++) {
    uft[i] = {i, X[i]};
  }
  for (int i = 0; i < m; i++) {
    if (used[i]) {
      ans++;
      merge(edge[i].S.F, edge[i].S.S);
    }
  }
  for (int i = 0; i < m; i++) {
    if (!used[i]) {
      if (parent(edge[i].S.F) == parent(edge[i].S.S) &&
          uft[parent(edge[i].S.S)].S >= edge[i].F) {
        ans++;
      }
    }
  }
  cout << m - ans << endl;

  return 0;
}