虽然写了很久,但是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;
}