Problem p00777 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Edge {
public:
  int to, cost;
  Edge(int to, int cost) {
    this->to = to;
    this->cost = cost;
  }
};

vector<vector<int>> memo;

int solve(const vector<vector<Edge>> edges, int curr, int prev, int isBack) {
  if (edges[curr].size() == 1 && prev != -1)
    return 0;
  if (memo[isBack][curr] != -1)
    return memo[isBack][curr];

  int sum = 0;
  int maxDiff = 0;
  for (unsigned i = 0; i < edges[curr].size(); ++i) {
    int next = edges[curr][i].to;
    int cost = edges[curr][i].cost;
    if (next == prev) {
      sum += cost;
      if (isBack == 1)
        sum += cost;
    } else {
      sum += cost + solve(edges, next, curr, 1);
      if (isBack == 0) {
        int diff = solve(edges, next, curr, 1) - solve(edges, next, curr, 0);
        maxDiff = max(maxDiff, diff);
      }
    }
  }

  int ret = sum - maxDiff;
  return memo[isBack][curr] = ret;
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      return 0;

    vector<int> p(n + 11);
    for (int i = 2; i <= n; ++i)
      cin >> p[i];

    vector<vector<Edge>> edges(n + 1);
    for (int i = 2; i <= n; ++i) {
      int d;
      cin >> d;
      edges[i].push_back(Edge(p[i], d));
      edges[p[i]].push_back(Edge(i, d));
    }

    int ret = INT_MAX;
    for (int i = 1; i <= n; ++i) {
      memo.assign(2, vector<int>(n + 1, -1));
      ret = min(ret, solve(edges, i, -1, 0));
    }
    cout << ret << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Edge {
public:
  int to, cost;
  Edge(int to, int cost) {
    this->to = to;
    this->cost = cost;
  }
};

vector<vector<int>> memo;

int solve(const vector<vector<Edge>> &edges, int curr, int prev, int isBack) {
  if (edges[curr].size() == 1 && prev != -1)
    return 0;
  if (memo[isBack][curr] != -1)
    return memo[isBack][curr];

  int sum = 0;
  int maxDiff = 0;
  for (unsigned i = 0; i < edges[curr].size(); ++i) {
    int next = edges[curr][i].to;
    int cost = edges[curr][i].cost;
    if (next == prev) {
      sum += cost;
      if (isBack == 1)
        sum += cost;
    } else {
      sum += cost + solve(edges, next, curr, 1);
      if (isBack == 0) {
        int diff = solve(edges, next, curr, 1) - solve(edges, next, curr, 0);
        maxDiff = max(maxDiff, diff);
      }
    }
  }

  int ret = sum - maxDiff;
  return memo[isBack][curr] = ret;
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      return 0;

    vector<int> p(n + 11);
    for (int i = 2; i <= n; ++i)
      cin >> p[i];

    vector<vector<Edge>> edges(n + 1);
    for (int i = 2; i <= n; ++i) {
      int d;
      cin >> d;
      edges[i].push_back(Edge(p[i], d));
      edges[p[i]].push_back(Edge(i, d));
    }

    int ret = INT_MAX;
    for (int i = 1; i <= n; ++i) {
      memo.assign(2, vector<int>(n + 1, -1));
      ret = min(ret, solve(edges, i, -1, 0));
    }
    cout << ret << endl;
  }
}