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

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int INF = 1e15;
typedef pair<int, int> P;

struct Edge {
  int to, cost;
};

int n;
vector<Edge> G[801];
int ss;

int dfs(int v, int p) {
  // if ( ss == 3 ) cout << v << " " << p << endl;
  bool flg = false;
  for (Edge e : G[v]) {
    int to = e.to, cost = e.cost;
    if (to == p)
      continue;
    if (G[to].size() >= 2)
      flg = true;
  }

  if (!flg)
    return 0;

  int ret = 0;
  for (Edge e : G[v]) {
    int to = e.to, cost = e.cost;
    if (to == p)
      continue;
    if (G[to].size() == 1)
      continue;
    ret += dfs(to, v) + cost;
  }

  return ret;
}

int calc(int s) {
  ss = s;
  int ret = 0;
  int ma = 0;
  for (Edge e : G[s]) {
    int to = e.to, cost = e.cost;
    if (G[to].size() == 1)
      continue;
    int tmp = dfs(to, s) + cost;
    // if ( s == 7 ) cout << tmp << endl;
    ma = max(ma, tmp);
    ret += tmp * 2;
  }

  queue<P> q;
  vector<int> d(n, -1);
  q.push(P(s, 0));
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    int v = p.first, c = p.second;

    if (d[v] >= 0)
      continue;
    if (G[v].size() == 1)
      continue;

    d[v] = c;

    for (Edge e : G[v]) {
      int to = e.to, cost = e.cost;
      if (G[to].size() == 1)
        continue;
      q.push(P(to, c + cost));
    }
  }

  ma = 0;
  for (int i = 0; i < n; i++)
    ma = max(ma, d[i]);

  // if ( s == 3 ) cout << ma << endl;

  return ret - ma;
}

signed main() {

  while (cin >> n, n) {
    for (int i = 0; i < 801; i++)
      G[i].clear();
    int sum = 0;

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

    // for ( int i = 0; i < n; i++ ) cout << G[i].size() << endl;

    int ans = INF;
    int id = 0;
    for (int i = 0; i < n; i++) {
      // if ( ans > calc(i) ) id = i;
      ans = min(ans, calc(i));
    }

    // cout << id << endl;
    cout << ans + sum << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int INF = 1e15;
typedef pair<int, int> P;

struct Edge {
  int to, cost;
};

int n;
vector<Edge> G[801];
int ss;

int dfs(int v, int p) {
  // if ( ss == 7 ) cout << v << " " << p << endl;
  bool flg = false;
  for (Edge e : G[v]) {
    int to = e.to, cost = e.cost;
    if (to == p)
      continue;
    if (G[to].size() >= 2)
      flg = true;
  }

  if (!flg)
    return 0;

  int ret = 0;
  for (Edge e : G[v]) {
    int to = e.to, cost = e.cost;
    if (to == p)
      continue;
    ret += dfs(to, v) + cost;
  }

  return ret;
}

int calc(int s) {
  ss = s;
  int ret = 0;
  int ma = 0;
  for (Edge e : G[s]) {
    int to = e.to, cost = e.cost;
    if (G[to].size() == 1)
      continue;
    int tmp = dfs(to, s) + cost;
    // if ( s == 7 ) cout << tmp << endl;
    ma = max(ma, tmp);
    ret += tmp * 2;
  }

  queue<P> q;
  vector<int> d(n, -1);
  q.push(P(s, 0));
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    int v = p.first, c = p.second;

    if (d[v] >= 0)
      continue;
    if (G[v].size() == 1)
      continue;

    d[v] = c;

    for (Edge e : G[v]) {
      int to = e.to, cost = e.cost;
      if (G[to].size() == 1)
        continue;
      q.push(P(to, c + cost));
    }
  }

  ma = 0;
  for (int i = 0; i < n; i++)
    ma = max(ma, d[i]);

  return ret - ma;
}

signed main() {

  while (cin >> n, n) {
    for (int i = 0; i < 801; i++)
      G[i].clear();
    int sum = 0;

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

    // for ( int i = 0; i < n; i++ ) cout << G[i].size() << endl;

    int ans = INF;
    int id = 0;
    for (int i = 0; i < n; i++) {
      // if ( ans > calc(i) ) id = i;
      ans = min(ans, calc(i));
    }

    // cout << id << endl;
    cout << ans + sum << endl;
  }
  return 0;
}