#include <iostream>
#include <algorithm> // fill
#include <vector>
#include <utility> // pair
#include <stack>
#include <cassert>
using namespace std;

/* 解答方針
   どんなふうに撤去しても、撤去にかかるコストは橋のコストの和。
   そこで差がつくのは、島をめぐる順番。
   コストが節約できるのは次の2つ。
   1：行き止まりの島に行く必要はない
   2：最後に戻ってくる必要はない
   1は、深さ優先探索のように巡っていくことになる。そこで深さ優先探索のプログラムを改造する。
   2は、どうせなら「始点へ戻ってくるコストが最も高い地点」を終点にしてしまえば節約この上ない。そこで、見かけ上は始点まで戻ってくることにし、始点からの距離の最大値を持っておき、最後に引く。こうすることで「深さ優先探索」の「分かれ道でどっちに行こうか？」の曖昧さも解消できる。
   これ以上工夫は思いつかない。すべての頂点で試す。

   サンプルは通るんですが、本当にこれでいいのかは心配です。
 */

int costs[800][800]; // 隣接行列コスト入り
vector<int> passes[800]; // 隣接リスト

const int infty = 200000000;

int DFS(int r) { // rが始点
  bool visited[800];
  int parent[800]; // 訪問する原因となった数字。戻ってくるために必要。
  int dist[800]; // 始点からの距離
  fill(visited, visited+800, false);
  fill(parent, parent+800, 1000);
  fill(dist, dist+800, 0);
  stack<int> S;
  S.push(r);
  parent[r] = 2000;
  int ans = 0;
  dist[r] = 0;
  while (!S.empty()) {
    int u = S.top();
    S.pop();
    if (visited[u]) continue;
    // cerr << "now " << u << " is being visited" << endl;
    visited[u] = true;
    if (u != r) {
      assert(parent[u] < 800);
      // cerr << "cost " << costs[parent[u]][u] << " with " << parent[u] << endl;
      ans += costs[parent[u]][u];
      dist[u] = costs[parent[u]][u] + dist[parent[u]];
    }
    int count = 0;
    for (vector<int>::size_type i=0; i<passes[u].size(); i++) {
      int v = passes[u][i];
      if (visited[v]) continue;
      count++;
      parent[v] = u;
      S.push(v);
    }
    if (count == 0) { // 行き止まりに来ていたら戻る。
      // cerr << "returning at " << u << endl;
      if (u != r) {
	assert(parent[u] < 800);
	// cerr << "-2 * cost " << costs[parent[u]][u] << " with " << parent[u] << endl;
	ans -= 2 * costs[u][parent[u]]; // 本来uには行く必要はなかった。
	dist[u] = 0;
      }
      int granma;
      if (S.empty()) { // 始点に戻ってくる。
	granma = r;
      } else {
	int next = S.top(); // 絶対始点ではない。
	granma = parent[next]; // granmaまで戻る。
      }
      // cerr << "granma is " << granma << endl;
      while (u != granma) {
	// cerr << "cost " << costs[parent[u]][u] << " with " << parent[u] << endl;
	ans += costs[u][parent[u]];
	u = parent[u];
	// cerr << "now " << u << " is passed" << endl;
      }
    }
  }
  int maxd = 0;
  for (int i=0; i<800; i++) {
    if (maxd < dist[i]) {
      maxd = dist[i];
    }
  }
  ans -= maxd;
  return ans;
}

int main() {
  int n, p, d;
  while (scanf("%d", &n) && n) {
    // 初期化
    fill(&costs[0][0], &costs[0][0]+800*800, 0);
    for (int i=0; i<800; i++) {
      passes[i].clear();
    }
    // 入力
    int temppd[1000][2];
    for (int i=2; i<=n; i++) {
      scanf("%d", &p);
      int j = i-1;
      p--;
      temppd[j][0] = p;
    }
    for (int i=2; i<=n; i++) {
      scanf("%d", &d);
      int j = i-1;
      temppd[j][1] = d;
    }
    int sum = 0;
    for (int j=1; j<n; j++) {
      p = temppd[j][0];
      d = temppd[j][1];
      costs[j][p] = costs[p][j] = d;
      passes[j].push_back(p);
      passes[p].push_back(j);
      sum += d;
    }
    int min = infty;
    for (int r=0; r<n; r++) {
      // cerr << "r = " << r << endl;
      int temp = DFS(r);
      if (temp < min) min = temp;
    }
    printf("%d\n", sum+min);
  }
}

Measured memory_bytes: 3772