Codeforces Round #362 (Div. 2) D Puzzles(树形dp)

来源:互联网 发布:caffe fcn 训练 编辑:程序博客网 时间:2024/05/16 10:53

有点小失落,找以前的题做做。
参考:http://blog.csdn.net/libin66/article/details/51918509
这里边写的听详细,但是看了好久才看懂。说说我的理解。
概率或者期望一直不怎么会算,平时碰到算概率的,或者算期望的,基本就不做了。
这个题我感觉难的地方就是算期望,不过在大佬们看来这还是很水的。
在题解中,期望的计算分为了两部分,一部分是从父节点直接走到当前节点的,一部分是不直接走到当前节点的。后者倒是很容易看懂。但是前者,题解中说的是anw[2]=anw[1]+1,我是想不明白。我画图算了下,还真是这样。
想了下,从父节点直接一步走到当前节点的方法数,就是走到父节点的所有方法数,这样发父节点的所以,父节点的期望是父节点的所有time相加,除以有多少情况走到父节点。父节点直接走到当前节点的期望,就是那些所有的time都再+1,除以所有走到父节点的情况,每种情况都+1,再除以情况数,就相当与ans[son]=ans[father]+1。这只是这一部分的期望。另一部分就好懂多了。这里写图片描述

#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5+10;struct Edge{    int to,next;};Edge edge[MAXN*2];int head[MAXN];int siz[MAXN];double ans[MAXN];int tot;void init(){    memset(head,-1,sizeof(head));    tot = 0;}void addedge(int u, int v){    edge[tot].to = v;    edge[tot].next = head[u];    head[u] = tot++;}void dfs(int u, int fa){    siz[u] = 1;    int v;    for(int i = head[u]; i != -1; i = edge[i].next)    {        v = edge[i].to;        if(v == fa) continue;        dfs(v,u);        siz[u] += siz[v];    }}void odfs(int u,int fa){    for(int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        if(v == fa) continue;        ans[v] = ans[u]+1.0+(siz[u]-siz[v]-1.0)/2.0;        odfs(v,u);    }}int main(){    int n,v;    init();    scanf("%d",&n);    for(int i = 2; i <= n; ++i)    {        scanf("%d",&v);        addedge(i,v);        addedge(v,i);    }    dfs(1,-1);    ans[1] = 1.0;    odfs(1,-1);    for(int i = 1; i <= n; ++i)        printf("%.2f ",ans[i]);    return 0;}
阅读全文
0 0
原创粉丝点击