Codeforces 696B Puzzles 树形期望dp

41 篇文章 0 订阅
31 篇文章 1 订阅

题意:

对一棵树进行dfs,求每个点访问次序的期望。

解:

对于父节点为x的子结点y1,y2,y3…yn

E[yi]=E[x]+1+f(yi)

f(yi)=p(0)E(0)+p(1)E(1)+p(2)E(2)+...+p(n1)E(n1)

( E(i) 代表有i个兄弟结点在y结点之前访问)

f(yi)=1n(E(0)+E(1)+E(2)+...+E(n1))

其中 E(0)=0,

E(1)=1C1n1sum(y1)+1C1n1sum(y2)++1C1n1sum(yn)

(sum(yi),sum(yi)yi)

=1C1n1jisum(yj)

E(2)=C1n2C2n1jisum(yj)

=2n1jisum(yj)

E(k)=Ck1n2Ckn1jisum(yj)

=kn1jisum(yj)

f(yi)=1n0+1+2+...+n1n1jisum(yj)

=1n(n1)n2(n1)jisum(yj)

=12jisum(yj)

E[yi]=E[x]+1+12jisum(yj)

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])
#define mem(a,x)  memset(a,x,sizeof a)
#define ysk(x)  (1<<(x))
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxn=  100000  ;
int n;
int fir[maxn+10],nex[2*maxn+10],to[2*maxn+10],nedge;
double ans[maxn+10];
int dp[maxn+10];
double E[maxn+10];
void add_edge(int x,int y)
{
    to[nedge]=y;
    nex[nedge]=fir[x];
    fir[x]= nedge++;
}

void dfs(int x)
{
    dp[x]=1;
    for(int i=fir[x];~i;i=nex[i])
    {
        int y=to[i];dfs(y);
        dp[x]+=dp[y];
    }


}

void dfs2(int x)
{
      for(int i=fir[x];~i;i=nex[i])
    {
        int y=to[i];
        E[y]=E[x]+1+ (dp[x]-1.0-dp[y] )/2;
        dfs2(y);
    }
}
int main()
{
   std::ios::sync_with_stdio(false);
   int x;
   while(cin>>n)
   {
       nedge=0;
       mes(fir,-1,n+1);
       for(int i=2;i<=n;i++)
       {
           cin>>x;
           add_edge(x,i);
       }
       E[1]=1;
       dfs(1);
       dfs2(1);
       for1(i,n)  printf("%.10f%c",E[i],i==n?'\n':' ');

   }

   return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值