Problem p00777 (C++) — buggy submission, verdict: Time Limit Exceeded

using namespace std;
#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF INT_MAX / 3

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define dump(x) cerr << #x << " = " << (x) << endl;

#define MAX_N 800

long long rt_mem[MAX_N];
int N;

struct Edge {
  int dest;
  int length;
};

vector<Edge> Graph[MAX_N];

long long round_trip(int start, int from) {
  if (rt_mem[start] >= 0) {
    return rt_mem[start];
  }
  long long ret = 0;
  int sz = Graph[start].size();
  REP(i, sz) {
    Edge e = Graph[start][i];
    if (e.dest == from) {
      continue;
    }

    if (Graph[e.dest].size() == 1) {
      ret += e.length;
      continue;
    }

    long long rt = round_trip(e.dest, start);
    ret += e.length + rt + e.length + e.length;
  }

  rt_mem[start] = ret;
  return ret;
}

long long one_way(int start, int from) {
  long long delta = 0;
  int sz = Graph[start].size();
  REP(i, sz) {
    Edge e = Graph[start][i];
    if (e.dest == from) {
      continue;
    }

    if (Graph[e.dest].size() == 1) {
      continue;
    }

    long long ow = one_way(e.dest, start);
    long long rt = round_trip(e.dest, start);
    delta = min(delta, -rt - e.length + ow);
  }
  long long ret = round_trip(start, from) + delta;
  return ret;
}

long long solve1() {
  long long ans = 100000 * 800 * 3;
  REP(i, N) {
    memset(rt_mem, -1, sizeof(rt_mem));
    ans = min(ans, one_way(i, -1));
  }
  return ans;
}

int load() {
  scanf("%d", &N);
  if (!N)
    return 0;

  int Ps[MAX_N];
  int Ds[MAX_N];

  FOR(i, 1, N) {
    scanf("%d", &Ps[i]);
    --Ps[i];
  }
  FOR(i, 1, N) { scanf("%d", &Ds[i]); }

  REP(i, N) { Graph[i].clear(); }

  FOR(i, 1, N) {
    int p = Ps[i];
    int d = Ds[i];
    Edge e;
    e.dest = p;
    e.length = d;
    Graph[i].push_back(e);
    e.dest = i;
    Graph[p].push_back(e);
  }
  return 1;
}

int main() {
  while (load()) {
    long long ans = solve1();
    printf("%lld\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

using namespace std;
#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF INT_MAX / 3

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define dump(x) cerr << #x << " = " << (x) << endl;

#define MAX_N 800

long long rt_mem[MAX_N];
long long ow_mem[MAX_N];
int N;

struct Edge {
  int dest;
  int length;
};

vector<Edge> Graph[MAX_N];

long long round_trip(int start, int from) {
  long long ret = 0;
  int sz = Graph[start].size();
  REP(i, sz) {
    Edge e = Graph[start][i];
    if (e.dest == from) {
      continue;
    }

    if (Graph[e.dest].size() == 1) {
      ret += e.length;
      continue;
    }

    long long rt = round_trip(e.dest, start);
    ret += e.length + rt + e.length + e.length;
  }

  rt_mem[start] = ret;
  return ret;
}

long long one_way(int start, int from) {
  long long delta = 0;
  int sz = Graph[start].size();
  REP(i, sz) {
    Edge e = Graph[start][i];
    if (e.dest == from) {
      continue;
    }

    if (Graph[e.dest].size() == 1) {
      continue;
    }

    long long ow = one_way(e.dest, start);
    long long rt = round_trip(e.dest, start);
    delta = min(delta, -rt - e.length + ow);
  }
  long long ret = round_trip(start, from) + delta;
  ow_mem[start] = ret;
  return ret;
}

long long solve1() {
  long long ans = 100000 * 800 * 3;
  REP(i, N) {
    memset(rt_mem, -1, sizeof(rt_mem));
    memset(ow_mem, -1, sizeof(ow_mem));
    ans = min(ans, one_way(i, -1));
    /*
    REP(j, N) {
      printf(" %lld", rt_mem[j]);
    }
    printf("\\n");
    REP(j, N) {
      printf(" %lld", ow_mem[j]);
    }
    printf("\\n\\n");
    */
  }
  return ans;
}

int load() {
  scanf("%d", &N);
  if (!N)
    return 0;

  int Ps[MAX_N];
  int Ds[MAX_N];

  FOR(i, 1, N) {
    scanf("%d", &Ps[i]);
    --Ps[i];
  }
  FOR(i, 1, N) { scanf("%d", &Ds[i]); }

  REP(i, N) { Graph[i].clear(); }

  FOR(i, 1, N) {
    int p = Ps[i];
    int d = Ds[i];
    Edge e;
    e.dest = p;
    e.length = d;
    Graph[i].push_back(e);
    e.dest = i;
    Graph[p].push_back(e);
  }
  return 1;
}

int main() {
  while (load()) {
    long long ans = solve1();
    printf("%lld\\n", ans);
  }
  return 0;
}