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

#include <iostream>
#include <vector>
#define inf 1000000000

using namespace std;

struct edge {
  int dist, cost;
  edge(int d, int c) { dist = d, cost = c; }
};

int n;
int p[805], d[805];
vector<edge> G[805];

int dist[805][805];
int memo[805][805];

int calc(int cur, int prev) {
  if (memo[cur][prev] != -1)
    return memo[cur][prev];

  int ret = 0, res;
  for (int i = 0; i < G[cur].size(); i++) {
    if (G[cur][i].dist == prev)
      continue;
    res = calc(G[cur][i].dist, cur);
    if (res)
      ret += G[cur][i].cost * 2;
    ret += G[cur][i].cost + res;
  }
  return memo[cur][prev] = ret;
}

void cdist(int s, int cur, int prev, int d) {
  dist[s][cur] = d;
  for (int i = 0; i < G[cur].size(); i++) {
    if (G[cur][i].dist == prev)
      continue;
    cdist(s, G[cur][i].dist, cur, d + G[cur][i].cost);
  }
}

int main(void) {
  while (1) {
    cin >> n;
    if (n == 0)
      break;

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

    for (int i = 1; i <= n; i++)
      G[i].clear();
    for (int i = 2; i <= n; i++) {
      G[i].push_back(edge(p[i], d[i]));
      G[p[i]].push_back(edge(i, d[i]));
    }

    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        dist[i][j] = inf;
      }
    }
    for (int i = 1; i <= n; i++)
      cdist(i, i, -1, 0);

    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        memo[i][j] = -1;
      }
    }

    int ans = inf, cost1, cost2;
    for (int i = 1; i <= n; i++) {
      if (G[i].size() == 1)
        continue;
      for (int j = 1; j <= n; j++) {
        if (G[j].size() == 1)
          continue;
        ans = min(ans, calc(i, i) - (dist[i][j]));
      }
    }
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
#define inf 1000000000

using namespace std;

struct edge {
  int dist, cost;
  edge(int d, int c) { dist = d, cost = c; }
};

int n;
int p[805], d[805];
vector<edge> G[805];

int dist[805][805];

int calc(int cur, int prev) {
  int ret = 0, res;
  for (int i = 0; i < G[cur].size(); i++) {
    if (G[cur][i].dist == prev)
      continue;
    res = calc(G[cur][i].dist, cur);
    if (res)
      ret += G[cur][i].cost * 2;
    ret += G[cur][i].cost + res;
  }
  return ret;
}

void cdist(int s, int cur, int prev, int d) {
  dist[s][cur] = d;
  for (int i = 0; i < G[cur].size(); i++) {
    if (G[cur][i].dist == prev)
      continue;
    cdist(s, G[cur][i].dist, cur, d + G[cur][i].cost);
  }
}

int main(void) {
  while (1) {
    cin >> n;
    if (n == 0)
      break;

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

    for (int i = 1; i <= n; i++)
      G[i].clear();
    for (int i = 2; i <= n; i++) {
      G[i].push_back(edge(p[i], d[i]));
      G[p[i]].push_back(edge(i, d[i]));
    }

    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        dist[i][j] = inf;
      }
    }
    for (int i = 1; i <= n; i++) {
      cdist(i, i, -1, 0);
    }

    int ans = inf, cost1, cost2;
    for (int i = 1; i <= n; i++) {
      if (G[i].size() == 1)
        continue;
      for (int j = 1; j <= n; j++) {
        if (G[j].size() == 1)
          continue;
        ans = min(ans, calc(i, -1) - (dist[i][j]));
      }
    }
    cout << ans << endl;
  }

  return 0;
}