Problem p03532 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; i++)
#define DREP(i, a, b) for (int i = (a), _end_ = (b); i >= _end_; i--)
#define EREP(i, a) for (int i = start[(a)]; i; i = e[i].next)
template <class T> inline void chkmax(T &a, T b) {
  if (a < b)
    a = b;
}
template <class T> inline void chkmin(T &a, T b) {
  if (a > b)
    a = b;
}
#define fi first
#define se second
#define mkr(a, b) make_pair(a, b)
inline int read() {
  int sum = 0, p = 1;
  char ch = getchar();
  while (!(('0' <= ch && ch <= '9') || ch == '-'))
    ch = getchar();
  if (ch == '-')
    p = -1, ch = getchar();
  while ('0' <= ch && ch <= '9')
    sum = sum * 10 + ch - 48, ch = getchar();
  return sum * p;
}

const int maxn = 2e5 + 20;
const int inf = 0x3f3f3f3f;
const ll Inf = 1ll << 60;

struct node {
  int v, next, w;
};
node e[maxn << 1];
int cnt, start[maxn];
inline void addedge(int u, int v, int w) {
  e[++cnt] = (node){v, start[u], w};
  start[u] = cnt;
}

int n, w[maxn];

inline void init() {
  n = read();
  REP(i, 1, n) w[i] = read();
  REP(i, 1, n - 1) {
    int u = read(), v = read(), w = read();
    addedge(u, v, w);
    addedge(v, u, w);
  }
}

int mn, rt, sz[maxn], sum;

struct Edge {
  int u, v;
  ll w;
};
Edge E[maxn << 5];
int m;

int vis[maxn];
ll MN;
int MNID;
int st[maxn], top;
ll stw[maxn];

void findroot(int u, int fa) {
  sz[u] = 1;
  int mx = 0;
  EREP(i, u) {
    int v = e[i].v;
    if (v == fa || vis[v])
      continue;
    findroot(v, u);
    chkmax(mx, sz[v]);
  }
  chkmax(mx, sum - sz[u]);
  if (mx < mn)
    mn = mx, rt = u;
}

void Calc(int u, int fa, ll dis) {
  st[++top] = u;
  stw[top] = dis + w[u];
  if (MN > dis + w[u])
    MN = dis + w[u], MNID = u;
  EREP(i, u) {
    int v = e[i].v;
    if (vis[v] || v == fa)
      continue;
    Calc(v, u, dis + e[i].w);
  }
}

void solve(int u) {
  vis[u] = 1;
  int Sum = sum;
  MN = 1ll << 60;
  top = 0;
  Calc(u, 0, 0);
  REP(i, 1, top) E[++m] = (Edge){MNID, st[i], stw[i] + MN};

  EREP(i, u) {
    int v = e[i].v;
    if (vis[v])
      continue;
    sum = sz[v] < sz[u] ? sz[v] : Sum - sz[u];
    mn = inf;
    findroot(v, u);
    solve(rt);
  }
}

inline bool cmp(Edge a, Edge b) { return a.w < b.w; }
int fa[maxn];
int fin(int x) { return x == fa[x] ? x : fa[x] = fin(fa[x]); }
inline void merge(int x, int y) {
  x = fin(x);
  y = fin(y);
  fa[y] = x;
}

inline void doing() {
  sum = n;
  mn = inf;
  findroot(1, 0);
  solve(rt);

  sort(E + 1, E + m + 1, cmp);
  REP(i, 1, n) fa[i] = i;
  ll ans = 0;
  REP(i, 1, m) {
    int u = E[i].u, v = E[i].v;
    if (fin(u) == fin(v))
      continue;
    merge(u, v);
    ans += E[i].w;
  }
  printf("%lld\n", ans);
}

int main() {
  init();
  doing();
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; i++)
#define DREP(i, a, b) for (int i = (a), _end_ = (b); i >= _end_; i--)
#define EREP(i, a) for (int i = start[(a)]; i; i = e[i].next)
template <class T> inline void chkmax(T &a, T b) {
  if (a < b)
    a = b;
}
template <class T> inline void chkmin(T &a, T b) {
  if (a > b)
    a = b;
}
#define fi first
#define se second
#define mkr(a, b) make_pair(a, b)
inline int read() {
  int sum = 0, p = 1;
  char ch = getchar();
  while (!(('0' <= ch && ch <= '9') || ch == '-'))
    ch = getchar();
  if (ch == '-')
    p = -1, ch = getchar();
  while ('0' <= ch && ch <= '9')
    sum = sum * 10 + ch - 48, ch = getchar();
  return sum * p;
}

const int maxn = 2e5 + 20;
const int inf = 0x3f3f3f3f;
const ll Inf = 1ll << 60;

struct node {
  int v, next, w;
};
node e[maxn << 1];
int cnt, start[maxn];
inline void addedge(int u, int v, int w) {
  e[++cnt] = (node){v, start[u], w};
  start[u] = cnt;
}

int n, w[maxn];

inline void init() {
  n = read();
  REP(i, 1, n) w[i] = read();
  REP(i, 1, n - 1) {
    int u = read(), v = read(), w = read();
    addedge(u, v, w);
    addedge(v, u, w);
  }
}

int mn, rt, sz[maxn], sum;

struct Edge {
  int u, v;
  ll w;
};
Edge E[maxn << 5];
int m;

int vis[maxn];
ll MN;
int MNID;
int st[maxn], top;
ll stw[maxn];

void findroot(int u, int fa) {
  sz[u] = 1;
  int mx = 0;
  EREP(i, u) {
    int v = e[i].v;
    if (v == fa || vis[v])
      continue;
    findroot(v, u);
    sz[u] += sz[v];
    chkmax(mx, sz[v]);
  }
  chkmax(mx, sum - sz[u]);
  if (mx < mn)
    mn = mx, rt = u;
}

void Calc(int u, int fa, ll dis) {
  st[++top] = u;
  stw[top] = dis + w[u];
  if (MN > dis + w[u])
    MN = dis + w[u], MNID = u;
  EREP(i, u) {
    int v = e[i].v;
    if (vis[v] || v == fa)
      continue;
    Calc(v, u, dis + e[i].w);
  }
}

void solve(int u) {
  vis[u] = 1;
  int Sum = sum;
  MN = 1ll << 60;
  top = 0;
  Calc(u, 0, 0);
  REP(i, 1, top) E[++m] = (Edge){MNID, st[i], stw[i] + MN};

  EREP(i, u) {
    int v = e[i].v;
    if (vis[v])
      continue;
    sum = sz[v] < sz[u] ? sz[v] : Sum - sz[u];
    mn = inf;
    findroot(v, u);
    solve(rt);
  }
}

inline bool cmp(Edge a, Edge b) { return a.w < b.w; }
int fa[maxn];
int fin(int x) { return x == fa[x] ? x : fa[x] = fin(fa[x]); }
inline void merge(int x, int y) {
  x = fin(x);
  y = fin(y);
  fa[y] = x;
}

inline void doing() {
  sum = n;
  mn = inf;
  findroot(1, 0);
  solve(rt);

  sort(E + 1, E + m + 1, cmp);
  REP(i, 1, n) fa[i] = i;
  ll ans = 0;
  REP(i, 1, m) {
    int u = E[i].u, v = E[i].v;
    if (fin(u) == fin(v))
      continue;
    merge(u, v);
    ans += E[i].w;
  }
  printf("%lld\n", ans);
}

int main() {
  init();
  doing();
  return 0;
}