Problem p03532 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 2e5 + 7;
const ll inf = (ll)1e17 + 7;
struct e {
  int from, to, dis, nxt;
} edge[MAXN << 2];
struct po {
  int x, y;
  ll l;
  bool operator<(const po &rhs) const { return l < rhs.l; }
} a[MAXN * 20], g[MAXN << 2], pre;
int n, m, wson[MAXN], size[MAXN], vis[MAXN * 2];
int f[MAXN], tp = 0, num, head[MAXN << 1], root, sum, cnt;
ll ans, dep[MAXN], x[MAXN];
inline int read() {
  int x = 0, c = 1;
  char ch = ' ';
  while (ch < '0' || ch > '9')
    ch = getchar();
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  return x;
}
inline void add_edge(int from, int to, int dis) {
  edge[++num].nxt = head[from];
  edge[num].to = to;
  edge[num].dis = dis;
  head[from] = num;
}
inline void get_root(int u, int fa) {
  size[u] = 1;
  wson[u] = 0;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (vis[v] || v == fa)
      continue;
    get_root(v, u);
    size[u] += size[v];
    wson[u] = max(wson[u], size[v]);
  }
  wson[u] = max(wson[u], sum - size[u]);
  root = (wson[u] < wson[root] ? u : root);
}
inline void dfs(int u, int fa, ll d) {
  g[++tp] = (po){u, 0, d + x[u]};
  pre = min(pre, g[tp]);
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (vis[v] || v == fa)
      continue;
    dfs(v, u, d + edge[i].dis);
  }
}
inline void solve(int u) {
  pre = (po){0, 0, inf};
  vis[u] = 1;
  tp = 0;
  dfs(u, 0, 0);
  for (int i = 1; i <= tp; i++)
    a[++cnt] = (po){pre.x, g[i].x, pre.l + g[i].l};
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (vis[v])
      continue;
    sum = size[v];
    root = 0;
    get_root(v, u);
    solve(root);
  }
}
int find(int x) { return f[x] == x ? f[x] : f[x] = find(f[x]); }
int main() {
  freopen("data.in", "r", stdin);
  //	freopen("my.out","w",stdout);
  n = read();
  for (int i = 1; i <= n; i++)
    x[i] = read();
  for (int i = 1; i <= n - 1; i++) {
    int u, v, l;
    u = read();
    v = read();
    l = read();
    add_edge(u, v, l);
    add_edge(v, u, l);
  }
  wson[0] = 10000007;
  sum = n;

  get_root(1, 0);

  solve(root);

  sort(a + 1, a + cnt + 1);
  for (int i = 1; i <= n; i++)
    f[i] = i;
  for (int i = 1; i <= cnt; i++) {
    int r1 = find(a[i].x), r2 = find(a[i].y);
    if (r1 != r2) {
      ans += a[i].l;
      f[r1] = r2;
    }
  }
  cout << ans;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 2e5 + 7;
const ll inf = (ll)1e17 + 7;
struct e {
  int from, to, dis, nxt;
} edge[MAXN << 2];
struct po {
  int x, y;
  ll l;
  bool operator<(const po &rhs) const { return l < rhs.l; }
} a[MAXN * 20], g[MAXN << 2], pre;
int n, m, wson[MAXN], size[MAXN], vis[MAXN * 2];
int f[MAXN], tp = 0, num, head[MAXN << 1], root, sum, cnt;
ll ans, dep[MAXN], x[MAXN];
inline int read() {
  int x = 0, c = 1;
  char ch = ' ';
  while (ch < '0' || ch > '9')
    ch = getchar();
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  return x;
}
inline void add_edge(int from, int to, int dis) {
  edge[++num].nxt = head[from];
  edge[num].to = to;
  edge[num].dis = dis;
  head[from] = num;
}
inline void get_root(int u, int fa) {
  size[u] = 1;
  wson[u] = 0;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (vis[v] || v == fa)
      continue;
    get_root(v, u);
    size[u] += size[v];
    wson[u] = max(wson[u], size[v]);
  }
  wson[u] = max(wson[u], sum - size[u]);
  root = (wson[u] < wson[root] ? u : root);
}
inline void dfs(int u, int fa, ll d) {
  g[++tp] = (po){u, 0, d + x[u]};
  pre = min(pre, g[tp]);
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (vis[v] || v == fa)
      continue;
    dfs(v, u, d + edge[i].dis);
  }
}
inline void solve(int u) {
  pre = (po){0, 0, inf};
  vis[u] = 1;
  tp = 0;
  dfs(u, 0, 0);
  for (int i = 1; i <= tp; i++)
    a[++cnt] = (po){pre.x, g[i].x, pre.l + g[i].l};
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (vis[v])
      continue;
    sum = size[v];
    root = 0;
    get_root(v, u);
    solve(root);
  }
}
int find(int x) { return f[x] == x ? f[x] : f[x] = find(f[x]); }
int main() {
  //	freopen("data.in","r",stdin);
  //	freopen("my.out","w",stdout);
  n = read();
  for (int i = 1; i <= n; i++)
    x[i] = read();
  for (int i = 1; i <= n - 1; i++) {
    int u, v, l;
    u = read();
    v = read();
    l = read();
    add_edge(u, v, l);
    add_edge(v, u, l);
  }
  wson[0] = 10000007;
  sum = n;

  get_root(1, 0);

  solve(root);

  sort(a + 1, a + cnt + 1);
  for (int i = 1; i <= n; i++)
    f[i] = i;
  for (int i = 1; i <= cnt; i++) {
    int r1 = find(a[i].x), r2 = find(a[i].y);
    if (r1 != r2) {
      ans += a[i].l;
      f[r1] = r2;
    }
  }
  cout << ans;
}