pku 2057 The Lost House 树形DP
http://poj.org/problem?id=2057
题意:
蜗牛的房子遗失在了一棵树的某个叶子结点上,它要从根结点出发开始寻找它的房子。有一些中间结点可能会住着一些虫子,这些虫子会告诉蜗牛它的房子是否在以这个中间结点为根的子树上,这样蜗牛就不用白跑路了。当然,如果有些结点没有住着虫子的话,那么可怜的蜗牛只有靠自己决定访问顺序来探索了。假设蜗牛走过一条边的耗费都是1,且房子遗失在每个叶子结点的概率都是相等的,那么请问蜗牛找到他的房子的最小数学期望值?
思路:
http://blog.sina.com.cn/s/blog_5f5353cc0100hd08.html (觉得这里讲的比较清楚)
View Code
#include <algorithm> #include <iostream> #include <cstdio> #include <cstring> #define maxn 1005 #define CL(a,num) memset(a,num,sizeof(a)) using namespace std; struct node { int leaf; int fail; int succ; }p[maxn]; int map[maxn][19]; int ct[maxn],worm[maxn]; int n; int cmp(int a,int b) { return (p[a].fail + 2)*p[b].leaf < (p[b].fail + 2)*p[a].leaf; } void dfs(int u) { int i; if (ct[u] == 0) { p[u].leaf = 1; p[u].fail = p[u].succ = 0; return ; } for (i = 1; i <= ct[u]; ++i) { int v = map[u][i]; dfs(v); p[u].leaf += p[v].leaf; if (worm[v] == 1) p[v].fail = 0; p[u].fail += p[v].fail + 2; } sort(map[u] + 1,map[u] + ct[u] + 1,cmp); int sum = 0; for (i = 1; i <= ct[u]; ++i) { int v = map[u][i]; p[u].succ += (sum + 1)*p[v].leaf + p[v].succ; sum += p[v].fail + 2; } } int main() { //freopen("din.txt","r",stdin); int i,a; char mk[3]; while (~scanf("%d",&n)) { if (!n) break; CL(map,0); CL(mk,0); CL(ct,0); CL(worm,0); CL(p,0); for (i = 1; i <= n; ++i) { scanf("%d%s",&a,mk); if (a != -1) map[a][++ct[a]] = i; if (mk[0] == 'Y') worm[i] = 1; } dfs(1); double ans = ((double)p[1].succ)/(1.0*p[1].leaf); printf("%.4lf\n",ans); } return 0; }