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

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>

#pragma warning(disable : 4996)

#define INF (1 << 29)

using namespace std;

int main() {
  int n, sum;

  while (true) {
    scanf("%d", &n);
    sum = 0;

    if (n == 0)
      break;

    vector<int> p(n - 1);
    vector<int> d(n - 1);

    vector<vector<pair<int, int>>> T(n);

    for (int i = 0; i < n - 1; i++) {
      scanf("%d", &p[i]);
    }
    for (int i = 0; i < n - 1; i++) {
      scanf("%d", &d[i]);
      sum += d[i];
    }

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

    vector<vector<int>> dists(n, vector<int>(n, INF));

    for (int i = 0; i < n; i++) {
      priority_queue<pair<int, int>, vector<pair<int, int>>,
                     greater<pair<int, int>>>
          que;

      que.push(make_pair(0, i));
      dists[i][i] = 0;

      while (!que.empty()) {
        pair<int, int> p1 = que.top();
        que.pop();

        int node = p1.second;
        int dist = p1.first;

        for (int j = 0; j < T[node].size(); j++) {
          if (dists[i][T[node][j].first] == INF) {
            dists[i][T[node][j].first] = dist + T[node][j].second;

            que.push(make_pair(dists[i][T[node][j].first], T[node][j].first));
          }
        }
      }
    }

    vector<int> nodes(n);

    for (int i = 0; i < n; i++) {
      nodes[i] = T[i].size();
    }

    int sum2 = 0;

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < nodes[i]; j++) {
        if (nodes[i] >= 2 && nodes[T[i][j].first] >= 2) {
          sum2 += T[i][j].second;
        }
      }
    }

    int ret = 0;

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (nodes[i] > 1 && nodes[j] > 1) {
          ret = max(ret, dists[i][j]);
        }
      }
    }

    printf("%d\\n", sum + sum2 - ret);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>

#pragma warning(disable : 4996)

#define INF (1 << 29)

using namespace std;

int main() {
  int n, sum;

  while (true) {
    scanf("%d", &n);
    sum = 0;

    if (n == 0)
      break;

    vector<int> p(n - 1);
    vector<int> d(n - 1);

    vector<vector<pair<int, int>>> T(n);

    for (int i = 0; i < n - 1; i++) {
      scanf("%d", &p[i]);
      sum += p[i];
    }
    for (int i = 0; i < n - 1; i++) {
      scanf("%d", &d[i]);
    }

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

    vector<vector<int>> dists(n, vector<int>(n, INF));

    for (int i = 0; i < n; i++) {
      priority_queue<pair<int, int>, vector<pair<int, int>>,
                     greater<pair<int, int>>>
          que;

      que.push(make_pair(0, i));

      while (!que.empty()) {
        pair<int, int> p1 = que.top();
        que.pop();

        int node = p1.second;
        int dist = p1.first;

        for (int j = 0; j < T[node].size(); j++) {
          if (dists[i][T[node][j].first] == INF) {
            dists[i][T[node][i].first] = dist + T[node][i].second;

            que.push(make_pair(dists[i][T[node][i].first], T[node][i].first));
          }
        }
      }
    }

    vector<int> nodes(n);

    for (int i = 0; i < n; i++) {
      nodes[i] = T[i].size();
    }

    int ret = 0;

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (nodes[i] > 1 && nodes[j] > 1) {
          ret = max(ret, dists[i][j]);
        }
      }
    }

    printf("%d\\n", ret + sum);
  }

  return 0;
}