Problem p00777 (C++)

Buggy submission (status: Runtime Error):
#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
#ifdef DEBUG
#define dump(...)                                                              \
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \
        << endl)
#else
#define dump(...)
#endif

typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src_, int dst_, Weight weight_)
      : src(src_), dst(dst_), weight(weight_) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
             e.src != f.src ? e.src < f.src
                            : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

int const inf = 1 << 29;

typedef pair<Weight, int> Result;
Result visit(int p, int v, const Matrix &g) {
  Result r(0, v);
  int n = g.size();
  rep(i, n) {
    if (i != p) {
      if (g[v][i] == inf)
        continue;
      Result t = visit(v, i, g);
      t.first += g[v][i];
      if (r.first < t.first)
        r = t;
    }
  }
  return r;
}
tuple<int, int, Weight> diameter(const Matrix &g, int start) {
  Result r = visit(-1, start, g);
  Result t = visit(-1, r.second, g);
  return mt(r.second, t.second,
            t.first); // (r.second, t.second) is farthest pair
}

Matrix mat;
int deg[1000];
int n;

int solve(int p, int v) {
  int res = 0;
  rep(i, n) {
    if (i == p)
      continue;
    if (mat[v][i] == inf)
      continue;
    res += mat[v][i];
    res += solve(v, i);
  }
  return res;
}

int main() {
#ifdef LOCAL
  freopen("in", "r", stdin);
#endif

  while (cin >> n && n) {
    mat.assign(n, Array(n, inf));
    int ans = 0;
    rep(i, n) deg[i] = 0;
    {
      int p[800], d[100];
      rep(i, n - 1) cin >> p[i];
      rep(i, n - 1) cin >> d[i];
      rep(i, n - 1) {
        p[i]--;
        mat[i + 1][p[i]] = mat[p[i]][i + 1] = d[i];
        deg[i + 1]++;
        deg[p[i]]++;
      }
    }

    int t = 0;
    rep(i, n) {
      if (deg[i] == 1) {
        rep(j, n) {
          if (mat[i][j] != inf) {
            t += mat[i][j];
            mat[i][j] = inf;
            mat[j][i] = inf;
          }
        }
      }
    }

    ans += t;
    int u = 0;
    rep(i, n) {
      deg[i] = 0;
      rep(j, n) {
        if (mat[i][j] != inf) {
          deg[i]++;
          u += mat[i][j];
        }
      }
    }
    ans += u / 2 * 3;

    int start = -1;
    rep(i, n) {
      if (deg[i] == 0)
        continue;
      start = i;
      break;
    }
    if (start == -1) {
      cout << ans << endl;
    } else {
      int a, b, d;
      vi dist, prev, path;
      tie(a, b, d) = diameter(mat, start);
      ans -= d;
      cout << ans << endl;
    }
  }
}

Fixed submission:
#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
#ifdef DEBUG
#define dump(...)                                                              \
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \
        << endl)
#else
#define dump(...)
#endif

typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src_, int dst_, Weight weight_)
      : src(src_), dst(dst_), weight(weight_) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
             e.src != f.src ? e.src < f.src
                            : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

int const inf = 1 << 29;

typedef pair<Weight, int> Result;
Result visit(int p, int v, const Matrix &g) {
  Result r(0, v);
  int n = g.size();
  rep(i, n) {
    if (i != p) {
      if (g[v][i] == inf)
        continue;
      Result t = visit(v, i, g);
      t.first += g[v][i];
      if (r.first < t.first)
        r = t;
    }
  }
  return r;
}
tuple<int, int, Weight> diameter(const Matrix &g, int start) {
  Result r = visit(-1, start, g);
  Result t = visit(-1, r.second, g);
  return mt(r.second, t.second,
            t.first); // (r.second, t.second) is farthest pair
}

Matrix mat;
int deg[1000];
int n;

int solve(int p, int v) {
  int res = 0;
  rep(i, n) {
    if (i == p)
      continue;
    if (mat[v][i] == inf)
      continue;
    res += mat[v][i];
    res += solve(v, i);
  }
  return res;
}

int main() {
#ifdef LOCAL
  freopen("in", "r", stdin);
#endif

  while (cin >> n && n) {
    mat.assign(n, Array(n, inf));
    int ans = 0;
    rep(i, n) deg[i] = 0;
    {
      int p[1000], d[1000];
      rep(i, n - 1) cin >> p[i];
      rep(i, n - 1) cin >> d[i];
      rep(i, n - 1) {
        p[i]--;
        mat[i + 1][p[i]] = mat[p[i]][i + 1] = d[i];
        deg[i + 1]++;
        deg[p[i]]++;
      }
    }

    int t = 0;
    rep(i, n) {
      if (deg[i] == 1) {
        rep(j, n) {
          if (mat[i][j] != inf) {
            t += mat[i][j];
            mat[i][j] = inf;
            mat[j][i] = inf;
          }
        }
      }
    }

    ans += t;
    int u = 0;
    rep(i, n) {
      deg[i] = 0;
      rep(j, n) {
        if (mat[i][j] != inf) {
          deg[i]++;
          u += mat[i][j];
        }
      }
    }
    ans += u / 2 * 3;

    int start = -1;
    rep(i, n) {
      if (deg[i] == 0)
        continue;
      start = i;
      break;
    }
    if (start == -1) {
      cout << ans << endl;
    } else {
      int a, b, d;
      vi dist, prev, path;
      tie(a, b, d) = diameter(mat, start);
      ans -= d;
      cout << ans << endl;
    }
  }
}