Problem p03532 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using std::max;
using std::min;
using std::sort;
using std::swap;
typedef long long ll;

template <typename T> void read(T &x) {
  int flag = 1;
  x = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      flag = -flag;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  x *= flag;
}

const int N = 1e6 + 10;
int n, w[N], Size, MX, rt, siz[N], fa[N];
int cnt, from[N], to[N << 1], dis[N << 1], nxt[N << 1];
bool vis[N];
inline void addEdge(int u, int v, int w) {
  to[++cnt] = v, dis[cnt] = w, nxt[cnt] = from[u], from[u] = cnt;
}
struct Edge {
  int u, v;
  ll w;
} e[N];
int m;
inline bool operator<(const Edge &a, const Edge &b) { return a.w < b.w; }

void getrt(int u, int fa) {
  int maxpart = 0;
  siz[u] = 1;
  for (int i = from[u]; i; i = nxt[i]) {
    int v = to[i];
    if (vis[v] || v == fa)
      continue;
    getrt(v, u), siz[u] += siz[v];
    maxpart = max(maxpart, siz[v]);
  }
  maxpart = max(maxpart, Size - siz[u]);
  if (maxpart < MX)
    MX = maxpart, rt = u;
}
int P;
ll val, ans;

void dfs(int u, int fa, ll dep) {
  if (dep + w[u] < val)
    val = dep + w[u], P = u;
  for (int i = from[u]; i; i = nxt[i])
    if (!vis[to[i]] && to[i] != fa)
      dfs(to[i], u, dep + dis[i]);
}

void Link(int u, int fa, ll dep) {
  e[++m] = (Edge){u, P, val + dep + w[u]};
  for (int i = from[u]; i; i = nxt[i])
    if (!vis[to[i]] && to[i] != fa)
      Link(to[i], u, dep + dis[i]);
}

void doit(int u) {
  vis[u] = 1, val = 1e18, P = 0;
  dfs(u, 0, 0), Link(u, 0, 0);
  for (int i = from[u]; i; i = nxt[i]) {
    int v = to[i];
    if (vis[v])
      continue;
    Size = MX = siz[v], getrt(v, u), doit(rt);
  }
}

inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
int main() {
#ifdef OFFLINE_JUDGE
  freopen("233.in", "r", stdin);
  freopen("233.out", "w", stdout);
#endif
  read(n);
  for (int i = 1; i <= n; ++i)
    read(w[i]);
  for (int i = 1, u, v, w; i < n; ++i) {
    read(u), read(v), read(w);
    addEdge(u, v, w), addEdge(v, u, w);
  }
  Size = MX = n;
  getrt(1, 0), doit(rt);
  sort(e + 1, e + m + 1);
  int blo = n;
  for (int i = 1; i <= n; ++i)
    fa[i] = i;
  for (int i = 1; i <= m && blo > 1; ++i) {
    int u = find(e[i].u), v = find(e[i].v);
    if (u != v)
      ans += e[i].w, fa[u] = v, --blo;
  }
  printf("%lld\n", ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using std::max;
using std::min;
using std::sort;
using std::swap;
typedef long long ll;

template <typename T> void read(T &x) {
  int flag = 1;
  x = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      flag = -flag;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  x *= flag;
}

const int N = 1e7 + 10;
int n, w[N], Size, MX, rt, siz[N], fa[N];
int cnt, from[N], to[N << 1], dis[N << 1], nxt[N << 1];
bool vis[N];
inline void addEdge(int u, int v, int w) {
  to[++cnt] = v, dis[cnt] = w, nxt[cnt] = from[u], from[u] = cnt;
}
struct Edge {
  int u, v;
  ll w;
} e[N];
int m;
inline bool operator<(const Edge &a, const Edge &b) { return a.w < b.w; }

void getrt(int u, int fa) {
  int maxpart = 0;
  siz[u] = 1;
  for (int i = from[u]; i; i = nxt[i]) {
    int v = to[i];
    if (vis[v] || v == fa)
      continue;
    getrt(v, u), siz[u] += siz[v];
    maxpart = max(maxpart, siz[v]);
  }
  maxpart = max(maxpart, Size - siz[u]);
  if (maxpart < MX)
    MX = maxpart, rt = u;
}
int P;
ll val, ans;

void dfs(int u, int fa, ll dep) {
  if (dep + w[u] < val)
    val = dep + w[u], P = u;
  for (int i = from[u]; i; i = nxt[i])
    if (!vis[to[i]] && to[i] != fa)
      dfs(to[i], u, dep + dis[i]);
}

void Link(int u, int fa, ll dep) {
  e[++m] = (Edge){u, P, val + dep + w[u]};
  for (int i = from[u]; i; i = nxt[i])
    if (!vis[to[i]] && to[i] != fa)
      Link(to[i], u, dep + dis[i]);
}

void doit(int u) {
  vis[u] = 1, val = 1e18, P = 0;
  dfs(u, 0, 0), Link(u, 0, 0);
  for (int i = from[u]; i; i = nxt[i]) {
    int v = to[i];
    if (vis[v])
      continue;
    Size = MX = siz[v], getrt(v, u), doit(rt);
  }
}

inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
int main() {
#ifdef OFFLINE_JUDGE
  freopen("233.in", "r", stdin);
  freopen("233.out", "w", stdout);
#endif
  read(n);
  for (int i = 1; i <= n; ++i)
    read(w[i]);
  for (int i = 1, u, v, w; i < n; ++i) {
    read(u), read(v), read(w);
    addEdge(u, v, w), addEdge(v, u, w);
  }
  Size = MX = n;
  getrt(1, 0), doit(rt);
  sort(e + 1, e + m + 1);
  int blo = n;
  for (int i = 1; i <= n; ++i)
    fa[i] = i;
  for (int i = 1; i <= m && blo > 1; ++i) {
    int u = find(e[i].u), v = find(e[i].v);
    if (u != v)
      ans += e[i].w, fa[u] = v, --blo;
  }
  printf("%lld\n", ans);
  return 0;
}