// 252K 32MS C++
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int MAX = 2005;
// dp[i][0]表示以该点为根的节点找不到房子时要爬行最少的距离, 这个值有什么用呢?
// 这个值就是用去计算房子落在其他叶子节点时,其对爬行距离的负面效应有多大.
// dp[i][1]表示以该点为根的节点在选择好所有分支点的爬行方案后,枚举完房子落在该
// 子树所有叶子节点上的总爬行距离的最小值,这是一个值告诉我们这棵子树对爬行距离
// 的正面效应有多大.那么有动态方程: ch[x]表示x节点一共有多少个叶子节点
int at[MAX];
int head[MAX];
struct Node {
int v;
int yes;
int next;
};
typedef struct Node Node;
Node e[MAX];
int ch[MAX];
int N;
int dp[MAX][2];
int idx;
void insert(int x, int y) {
++idx;
e[idx].v = y, e[idx].next = head[x];
head[x] = idx; // 建立邻接链表
}
bool cmp(int a, int b) {
return (dp[a][0]+2) * ch[b] < (dp[b][0]+2) * ch[a];
}
int dfs(int x) {
if (head[x] == -1) {
dp[x][0] = 0;
dp[x][1] = 0;
ch[x] = 1;
return 1;
}
vector<int> v;
for (int i = head[x]; i != -1; i = e[i].next) {
ch[x] += dfs(e[i].v);
v.push_back(e[i].v);
}
sort(v.begin(), v.end(), cmp);
for (int i = 0; i != v.size(); ++i) {
dp[x][1] += dp[x][0]*ch[v[i]] + dp[v[i]][1] + ch[v[i]];
dp[x][0] += dp[v[i]][0] + 2;
}
if (at[x]) {
dp[x][0] = 0;
}
return ch[x];
}
int main() {
int prev;
char ifHaveWorm[5];
while (scanf("%d", &N), N) {
idx = -1;
memset(head, 0xff, sizeof(head));
memset(dp, 0, sizeof(dp));
memset(ch, 0, sizeof(ch));
scanf("%d %s", &prev, ifHaveWorm);
for (int i = 2; i <= N; ++i) {
scanf("%d %s", &prev, ifHaveWorm);
at[i] = ifHaveWorm[0] == 'Y';
insert(prev, i);
}
dfs(1);
printf("%.4lf\n", 1.*dp[1][1]/ch[1]);
}
return 0;
}
MB的, head搞成char类型了。。。RE了好几次愣是没看出来.