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

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

struct Edge {
  int from, to, weight;
};
typedef vector<vector<Edge>> Graph;

tuple<int, int> farthest(const Graph &tree, const set<int> &vertex,
                         const Edge &pre) {
  tuple<int, int> res(pre.weight, pre.to);
  for (const auto &nex : tree[pre.to])
    if (vertex.count(nex.to))
      if (nex.to != pre.from)
        res = max(res, farthest(tree, vertex,
                                {nex.from, nex.to, pre.weight + nex.weight}));
  return res;
}

int diameter(const Graph &tree, const set<int> &vertex) {
  int w, v;
  tie(w, v) = farthest(tree, vertex, {-1, *begin(vertex), 0});
  tie(w, v) = farthest(tree, vertex, {v, v, 0});
  return w;
}

int main() {
  int n;
  while (cin >> n, n) {
    vector<int> p(n - 1), d(n - 1);
    for (auto &i : p)
      cin >> i, --i;
    for (auto &i : d)
      cin >> i;

    Graph tree(n);
    for (int i = 0; i < n - 1; ++i) {
      tree[p[i]].push_back({p[i], i + 1, d[i]});
      tree[i + 1].push_back({i + 1, p[i], d[i]});
    }

    int answer = 3 * accumulate(begin(d), end(d), 0);
    set<int> vertex;
    for (int i = 0; i < n; ++i)
      vertex.insert(i);
    for (int i = 0; i < n; ++i)
      if (tree[i].size() == 1) {
        vertex.erase(i);
        for (const auto &e : tree[i])
          answer -= 2 * e.weight;
      }
    answer -= diameter(tree, vertex);
    cout << answer << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

class Edge {
  int v0, v1, weight;

public:
  Edge(int v0, int v1, int w) : v0(v0), v1(v1), weight(w) {}
  int vertex(int n) const { return n == 0 ? v0 : v1; }
  bool include(int v) const { return v0 == v || v1 == v; }
  int cost() const { return weight; }
};

vector<int> leaf(int n, vector<Edge> &edge) {
  vector<int> result;
  vector<int> count(n, 0);
  for (const auto &e : edge) {
    ++count[e.vertex(0)];
    ++count[e.vertex(1)];
  };
  for (int i = 0; i < n; ++i)
    if (count[i] == 1)
      result.push_back(i);
  return result;
}

int main() {
  int n;
  while (cin >> n, n) {
    int answer = 0;
    vector<int> p(n - 1), d(n - 1);
    for (auto &i : p)
      cin >> i;
    for (auto &i : d)
      cin >> i;

    vector<Edge> edge;
    for (int i = 1; i < n; ++i)
      edge.push_back(Edge(i, p[i - 1] - 1, d[i - 1]));

    // ????????\\?¶???????????????????????????????????????????
    for (const auto &v : leaf(n, edge)) {
      for (int i = 0; i < edge.size(); ++i) {
        if (!edge[i].include(v))
          continue;
        answer += edge[i].cost();
        edge.erase(edge.begin() + i);
        break;
      }
    }

    // 2?????????????????? + ?£??????????????????????
    for (const auto &e : edge)
      answer += 3 * e.cost();

    // 1???????????????????????????
    const int INF = 1000000000;
    int maxcost = 0;
    vector<vector<int>> cost(n, vector<int>(n, INF));
    for (const auto &e : edge)
      cost[e.vertex(0)][e.vertex(1)] = cost[e.vertex(1)][e.vertex(0)] =
          e.cost();
    for (int k = 0; k < n; ++k)
      for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
          if (i != j)
            cost[i][j] = min(cost[i][j], cost[i][k] + cost[k][j]);
    for (const auto &u : leaf(n, edge))
      for (const auto &v : leaf(n, edge))
        if (cost[u][v] != INF)
          maxcost = max(maxcost, cost[u][v]);
    answer -= maxcost;

    cout << answer << endl;
  }
}