Problem p03344 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define fr first
#define sc second

template <int N = 100010> struct UF {
  int par[N], r[N];
  ll sum[N];
  priority_queue<P> *que[N];
  UF() {
    for (int i = 0; i < N; i++) {
      par[i] = i;
      r[i] = 0;
      sum[i] = 0;
      que[i] = new priority_queue<P>;
    }
  }
  void init() {
    for (int i = 0; i < N; i++) {
      par[i] = i;
      r[i] = 0;
      sum[i] = 0;
      if (que[i] != nullptr)
        delete que[i];
      que[i] = new priority_queue<P>;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unit_(int x, int y) {
    par[x] = y;
    sum[y] += sum[x];
    if (que[x]->size() < que[y]->size()) {
      while (!que[x]->empty()) {
        P p = que[x]->top();
        que[x]->pop();
        que[y]->push(p);
      }
      delete que[x];
      que[x] = nullptr;
    } else {
      while (!que[y]->empty()) {
        P p = que[y]->top();
        que[y]->pop();
        que[x]->push(p);
      }
      delete que[y];
      que[y] = que[x];
      que[x] = nullptr;
    }
    if (r[x] == r[y])
      r[y]++;
  }
  void unit(int x, int y) {
    if (same(x, y))
      return;
    x = find(x);
    y = find(y);
    if (r[x] < r[y]) {
      unit_(x, y);
    } else {
      unit_(y, x);
    }
  }
  void run(int v, int w) {
    while (1) {
      v = find(v);
      if (que[v]->empty())
        break;
      P p = que[v]->top();
      if (find(p.sc) == v)
        que[v]->pop();
      else if (p.fr + sum[v] + w >= 0) {
        que[v]->pop();
        unit(v, p.sc);
      } else
        break;
    }
  }
};

UF<100010> uf;

int main() {
  static int n, m;
  static int a[100010], b[100010];
  static int u[100010], v[100010];
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &a[i], &b[i]);
  }
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u[i], &v[i]);
    u[i]--;
    v[i]--;
  }

  if (n == 1) {
    cout << max(a[0], b[0]) << endl;
    return 0;
  }

  ll l = 0, r = 1000000000;
  while (l < r) {
    int mi = (l + r) / 2;
    uf.init();
    for (int i = 0; i < m; i++) {
      uf.que[u[i]]->push(P(b[v[i]] - a[v[i]], v[i]));
      uf.que[v[i]]->push(P(b[u[i]] - a[u[i]], u[i]));
    }
    for (int i = 0; i < n; i++) {
      uf.sum[i] = b[i];
    }
    for (int i = 0; i < n; i++) {
      if (a[i] <= b[i] + mi)
        uf.run(i, mi);
    }
    int root = uf.find(0);
    bool ok = true;
    for (int i = 0; i < n; i++) {
      ok &= uf.find(i) == root;
    }
    if (ok)
      r = mi;
    else
      l = mi + 1;
  }
  for (int i = 0; i < n; i++) {
    l += b[i];
  }
  cout << l << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

#define fr first
#define sc second

template <int N = 100010> struct UF {
  int par[N], r[N];
  ll sum[N];
  priority_queue<P> *que[N];
  UF() {
    for (int i = 0; i < N; i++) {
      par[i] = i;
      r[i] = 0;
      sum[i] = 0;
      que[i] = new priority_queue<P>;
    }
  }
  void init() {
    for (int i = 0; i < N; i++) {
      par[i] = i;
      r[i] = 0;
      sum[i] = 0;
      if (que[i] != nullptr)
        delete que[i];
      que[i] = new priority_queue<P>;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unit_(int x, int y) {
    par[x] = y;
    sum[y] += sum[x];
    if (que[x]->size() < que[y]->size()) {
      while (!que[x]->empty()) {
        P p = que[x]->top();
        que[x]->pop();
        que[y]->push(p);
      }
      delete que[x];
      que[x] = nullptr;
    } else {
      while (!que[y]->empty()) {
        P p = que[y]->top();
        que[y]->pop();
        que[x]->push(p);
      }
      delete que[y];
      que[y] = que[x];
      que[x] = nullptr;
    }
    if (r[x] == r[y])
      r[y]++;
  }
  void unit(int x, int y) {
    if (same(x, y))
      return;
    x = find(x);
    y = find(y);
    if (r[x] < r[y]) {
      unit_(x, y);
    } else {
      unit_(y, x);
    }
  }
  void run(int v, int w) {
    while (1) {
      v = find(v);
      if (que[v]->empty())
        break;
      P p = que[v]->top();
      if (find(p.sc) == v)
        que[v]->pop();
      else if (p.fr + sum[v] + w >= 0) {
        que[v]->pop();
        unit(v, p.sc);
      } else
        break;
    }
  }
};

UF<100010> uf;

int main() {
  static int n, m;
  static int a[100010], b[100010];
  static int u[100010], v[100010];
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &a[i], &b[i]);
  }
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u[i], &v[i]);
    u[i]--;
    v[i]--;
  }

  if (n == 1) {
    cout << max(a[0], b[0]) << endl;
    return 0;
  }

  ll l = 0, r = 1000000000;
  while (l < r) {
    int mi = (l + r) / 2;
    uf.init();
    for (int i = 0; i < m; i++) {
      uf.que[u[i]]->push(P(b[v[i]] - a[v[i]], v[i]));
      uf.que[v[i]]->push(P(b[u[i]] - a[u[i]], u[i]));
    }
    for (int i = 0; i < n; i++) {
      uf.sum[i] = b[i];
    }
    for (int i = 0; i < n; i++) {
      if (a[i] <= b[i] + mi)
        uf.run(i, mi);
    }
    int root = uf.find(0);
    bool ok = true;
    for (int i = 0; i < n; i++) {
      ok &= uf.find(i) == root;
    }
    if (ok)
      r = mi;
    else
      l = mi + 1;
  }
  for (int i = 0; i < n; i++) {
    l += b[i];
  }
  cout << l << endl;
}