Problem p03344 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
#define int ll
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<short> vs;
typedef vector<vs> vvs;
typedef vector<vvs> vvvs;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef pair<ld, ld> pld;
typedef complex<double> base;

#define mmin(a, b) a = min(a, (b))
#define mmax(a, b) a = max(a, (b))
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()
#define sqr(x) (x) * (x)
#define fori(i, n) for (int i = 0; i < int(n); ++i)
#define cint const int &
#define SZ(a) ((int)(a.size()))
#define watch(x) cout << (#x) << " = " << x << endl;

const double PI = 2 * acos(0.0);

template <class T> void show(const vector<T> &a) {
  for (T x : a)
    cout << x << " ";
  cout << endl;
}

const int N = 1e5 + 9;
const ll oo = 1e15;
int parent[N];
int is_free[N];
ll bsum[N];
vi g[N];
int n, m;
ll a[N], b[N];

set<int> inside[N];
set<pair<ll, int>> neibs[N];
ll gw, gb;
set<pair<ll, int>> fre;
int counter = 0;

void make_set(int v) {
  ++counter;
  inside[v].insert(v);
  parent[v] = v;
  bsum[v] = b[v];
  for (int to : g[v])
    neibs[v].insert(mp(a[to] - b[to], to));
}

int find_set(int v) {
  if (parent[v] == v)
    return v;
  return parent[v] = find_set(parent[v]);
}

void union_sets(int u, int v) {
  u = find_set(u);
  v = find_set(v);
  if (u == v)
    return;
  --counter;
  is_free[v] = 1;
  if (SZ(neibs[u]) < SZ(neibs[v]))
    swap(v, u);
  inside[u].insert(ALL(inside[v]));
  bsum[u] += bsum[v];
  parent[v] = u;
  neibs[u].insert(ALL(neibs[v]));
}

void add_to_free(int u) {
  while (!neibs[u].empty()) {
    bool ok = 0;
    if (inside[u].count((*neibs[u].begin()).second)) {
      ok = 1;
      neibs[u].erase(neibs[u].begin());
    }
    if (!ok)
      break;
  }
  if (neibs[u].empty()) {
    assert(counter == 1);
    return;
  }
  int superv = (*neibs[u].begin()).second;
  fre.insert(mp(a[superv] - b[superv] - bsum[u], u));
}

void add_to_cool(int v) {
  v = find_set(v);
  is_free[v] = 1;
  while (!neibs[v].empty() && (*neibs[v].begin()).first + gb - bsum[v] <= gw) {
    int u = (*neibs[v].begin()).second;
    neibs[v].erase(neibs[v].begin());
    union_sets(v, u);
    v = find_set(v);
  }
  add_to_free(v);
}

ll solve() {
  if (n == 1) {
    return a[1];
  }
  gb = accumulate(b + 1, b + n + 1, 0LL);
  fori(i, n) {
    make_set(i + 1);
    fre.insert(mp(a[i + 1] - b[i + 1], i + 1));
  }
  while (counter > 1) {
    ll minim = (*fre.begin()).first;
    // minim + gb <= gw
    // watch(minim);
    gw = minim + gb;
    while (!fre.empty() && (*fre.begin()).first + gb == gw) {
      int v = find_set((*fre.begin()).second);
      fre.erase(fre.begin());
      add_to_cool(v);
    }
  }
  return gw;
}

signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  cin >> n >> m;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i] >> b[i];
    mmax(a[i], b[i]);
  }
  fori(iter, m) {
    int u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }

  cout << solve() << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
#define int ll
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<short> vs;
typedef vector<vs> vvs;
typedef vector<vvs> vvvs;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef pair<ld, ld> pld;
typedef complex<double> base;

#define mmin(a, b) a = min(a, (b))
#define mmax(a, b) a = max(a, (b))
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()
#define sqr(x) (x) * (x)
#define fori(i, n) for (int i = 0; i < int(n); ++i)
#define cint const int &
#define SZ(a) ((int)(a.size()))
#define watch(x) cout << (#x) << " = " << x << endl;

const double PI = 2 * acos(0.0);

template <class T> void show(const vector<T> &a) {
  for (T x : a)
    cout << x << " ";
  cout << endl;
}

const int N = 1e5 + 9;
const ll oo = 1e15;
int parent[N];
int is_free[N];
ll bsum[N];
vi g[N];
int n, m;
ll a[N], b[N];

set<int> inside[N];
set<pair<ll, int>> neibs[N];
ll gw, gb;
set<pair<ll, int>> fre;
int counter = 0;

void make_set(int v) {
  ++counter;
  inside[v].insert(v);
  parent[v] = v;
  bsum[v] = b[v];
  for (int to : g[v])
    neibs[v].insert(mp(a[to] - b[to], to));
}

int find_set(int v) {
  if (parent[v] == v)
    return v;
  return parent[v] = find_set(parent[v]);
}

void union_sets(int u, int v) {
  u = find_set(u);
  v = find_set(v);
  if (u == v)
    return;
  --counter;
  is_free[v] = 1;
  if (SZ(inside[u]) < SZ(inside[v]))
    swap(v, u);
  inside[u].insert(ALL(inside[v]));
  bsum[u] += bsum[v];
  parent[v] = u;
  neibs[u].insert(ALL(neibs[v]));
}

void add_to_free(int u) {
  while (!neibs[u].empty()) {
    bool ok = 0;
    if (inside[u].count((*neibs[u].begin()).second)) {
      ok = 1;
      neibs[u].erase(neibs[u].begin());
    }
    if (!ok)
      break;
  }
  if (neibs[u].empty()) {
    assert(counter == 1);
    return;
  }
  int superv = (*neibs[u].begin()).second;
  fre.insert(mp(a[superv] - b[superv] - bsum[u], u));
}

void add_to_cool(int v) {
  v = find_set(v);
  is_free[v] = 1;
  while (!neibs[v].empty() && (*neibs[v].begin()).first + gb - bsum[v] <= gw) {
    int u = (*neibs[v].begin()).second;
    neibs[v].erase(neibs[v].begin());
    union_sets(v, u);
    v = find_set(v);
  }
  add_to_free(v);
}

ll solve() {
  if (n == 1) {
    return a[1];
  }
  gb = accumulate(b + 1, b + n + 1, 0LL);
  fori(i, n) {
    make_set(i + 1);
    fre.insert(mp(a[i + 1] - b[i + 1], i + 1));
  }
  while (counter > 1) {
    ll minim = (*fre.begin()).first;
    // minim + gb <= gw
    // watch(minim);
    gw = minim + gb;
    while (!fre.empty() && (*fre.begin()).first + gb == gw) {
      int v = find_set((*fre.begin()).second);
      fre.erase(fre.begin());
      add_to_cool(v);
    }
  }
  return gw;
}

signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  cin >> n >> m;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i] >> b[i];
    mmax(a[i], b[i]);
  }
  fori(iter, m) {
    int u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }

  cout << solve() << endl;
  return 0;
}