虽然写了很久,但是1A还是很开心的。。。。
这个题目找准状态转移,然后运用部分贪心优化一下。
int pos[1010];//标记当前节点是不是有虫子
int snode[1010];//标记当前节点为根的子树中包含的叶子节点。
int die[1010];//标记当前节点为根的子树中不含有房子的步数
int win[1010];//标记当前节点为根的子树中 含有房子的步数
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>vec[1010];
int pos[1010];//标记当前节点是不是有虫子
int snode[1010];//标记当前节点为根的子树中包含的叶子节点。
int die[1010];//标记当前节点为根的子树中不含有房子的步数
int win[1010];//标记当前节点为根的子树中 含有房子的步数
int n;
void init()
{
memset(pos,0,sizeof(pos));
memset(snode,0,sizeof(snode));
memset(die,0,sizeof(die));
memset(win,0,sizeof(win));
int i,pre;
char ps;
for(i=1;i<=n;i++)
{
pos[i]=0;
vec[i].clear();
}
for(i=1;i<=n;i++)
{
scanf("%d %c%*c",&pre,&ps);
if(pre==-1)continue;
vec[pre].push_back(i);
if(ps=='Y')pos[i]=1;
}
}
int cmp(int a,int b)
{
return (die[a]+2)*snode[b]<(die[b]+2)*snode[a];
}
void dos(int x)
{
int len=vec[x].size();
int i;
for(i=0;i<len;i++)
{
dos(vec[x][i]);
}
if(len==0)
{
snode[x]=1;
die[x]=0;
win[x]=0;
return ;
}
for(i=0;i<len;i++)
{
snode[x]+=snode[vec[x][i]];
if(pos[x]==0)die[x]+=die[vec[x][i]]+2;
}
int tmp[10];
for(i=0;i<len;i++)
{
tmp[i]=vec[x][i];
}
sort(tmp,tmp+len,cmp);
int j=0;
for(i=0;i<len;i++)
{
win[x]+=(j+1)*snode[tmp[i]]+win[tmp[i]];
j+=die[tmp[i]]+2;
}
}
int main()
{
while(scanf("%d%*c",&n)&&n)
{
init();
double ans;
dos(1);
ans=1.0*win[1]/snode[1];
printf("%.4lf\n",ans);
}
return 0;
}