poj 2057 树形dp 贪心
思路:设sum[i],le[i],back[i],worm[i]分别表示以i为根节点需要的完成步数,叶子节点数,失败回退步数,以及i是否有虫。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define Maxn 1010 using namespace std; int sum[Maxn],worm[Maxn],le[Maxn],vi[Maxn],head[Maxn],e,n,back[Maxn]; struct Edge{ int u,v,next; }edge[Maxn*Maxn]; void init() { memset(sum,0,sizeof(sum)); memset(worm,0,sizeof(worm)); memset(le,0,sizeof(le)); memset(vi,0,sizeof(vi)); memset(back,0,sizeof(back)); memset(head,-1,sizeof(head)); e=0; } void add(int u,int v) { edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++; } int cmp(int a,int b) { return (back[a]+2)*le[b]<(back[b]+2)*le[a]; } void dfs(int u) { int i,v,cnt; int use[10]; cnt=0; if(head[u]==-1) { le[u]=1; return ; } for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].v; dfs(v); use[++cnt]=v; le[u]+=le[v]; } sort(use+1,use+1+cnt,cmp); for(i=1;i<=cnt;i++) { sum[u]+=(back[u]+1)*le[use[i]]+sum[use[i]]; back[u]+=back[use[i]]+2; } if(worm[u]) back[u]=0; } int main() { int i,j,a; char str[2]; while(scanf("%d",&n),n) { init(); scanf("%d%s",&a,&str); if(str[0]=='Y') worm[1]=1; for(i=2;i<=n;i++) { scanf("%d%s",&a,&str); add(a,i); if(str[0]=='Y') worm[i]=1; } dfs(1); double temp=sum[1]; printf("%.4lf\n",sum[1]/(1.0*le[1])); } return 0; }