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

#include <algorithm>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> P;
#define EPS (1e-7)
#define INF 1e18
#define max(p, q) ((p) > (q) ? (p) : (q))
#define min(p, q) ((p) < (q) ? (p) : (q))
#define PI (acos(-1))

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, init, n) for (int i = init; i < (int)(n); i++)

int main() {
  ll N, M;
  cin >> N >> M;
  vector<ll> H(N);
  REP(i, N) cin >> H[i];
  ll a, b;
  vector<vector<ll>> v(N);
  REP(i, M) {
    cin >> a >> b;
    v[a - 1].push_back(b - 1);
    v[b - 1].push_back(a - 1);
  }
  vector<bool> t(N, true);
  ll ans = 0;
  REP(i, N) {
    if (!t[i])
      continue;
    ll st = H[i];
    for (auto iter : v[i])
      if (st <= H[iter])
        t[i] = false;
  }
  REP(i, N) if (t[i]) ans++;
  cout << ans << endl;

  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> P;
#define EPS (1e-7)
#define INF 1e18
#define max(p, q) ((p) > (q) ? (p) : (q))
#define min(p, q) ((p) < (q) ? (p) : (q))
#define PI (acos(-1))

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, init, n) for (int i = init; i < (int)(n); i++)

struct UnionFind {
  vector<ll> par;   // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
  vector<ll> _size; // 属する連結成分の大きさ

  UnionFind(ll N) : par(N), _size(N) { // 最初は全てが根であるとして初期化
    for (ll i = 0; i < N; i++) {
      par[i] = i;
      _size[i] = 1;
    }
  }

  ll root(ll x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(ll x, ll y) { // xとyの木を併合
    ll rx = root(x);       // xの根をrx
    ll ry = root(y);       // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    _size[ry] += _size[rx];
  }

  bool same(ll x, ll y) { // 2つのデータx, yが属する木が同じならtrueを返す
    ll rx = root(x);
    ll ry = root(y);
    return rx == ry;
  }

  ll size(ll x) {
    ll rx = root(x);
    return _size[rx];
  }
};

int main() {
  ll N, M;
  cin >> N >> M;
  vector<ll> H(N);
  REP(i, N) cin >> H[i];
  UnionFind u = UnionFind(N);
  ll a, b;
  REP(i, M) {
    cin >> a >> b;
    u.unite(a, b);
  }
  set<ll> s;
  REP(i, N) s.insert(u.root(i));
  ll ans = 0;
  map<ll, P> m;
  for (auto iter : s)
    m[iter] = P(0, 0);
  REP(i, N) {
    ll parent = u.root(i);
    if (m[parent].first == H[i])
      m[parent].second++;
    else if (m[parent].first < H[i])
      m[parent] = P(H[i], 1);
  }
  for (auto iter : s)
    ans += m[iter].second;
  cout << ans << endl;

  return 0;
}