码迷,mamicode.com
首页 > 其他好文 > 详细

CF696B Puzzles(期望dp)

时间:2018-12-01 22:04:12      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:+=   etc   problem   tps   mat   char   cpp   ref   dfs   

传送门

解题思路

  比较有意思的一道题。首先假如这个点\(x\)只有\(1\)个儿子\(u\),那么显然可得\(dp[u]=dp[x]+1\)。继续如果多加一个儿子\(p\),那么\(p\)\(u\)前面的概率就是\(1/2\),也就是说\(p\)对于\(u\)的答案有\(1/2\)的可能产生贡献,而产生的贡献为\(siz[p]\),那么继续归纳下去,就可以得出转移方程。\(dp[u]=dp[x]+1+(siz[x]-siz[u]-1)/2\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;
const int MAXN = 100005;

inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {f=ch==‘-‘?0:1;ch=getchar();}
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
    return f?x:-x;
}

int n,head[MAXN],cnt,to[MAXN],nxt[MAXN],siz[MAXN];
double ans[MAXN];

inline void add(int bg,int ed){
    to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
}

void dfs1(int x){
    int u;siz[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        u=to[i];dfs1(u);
        siz[x]+=siz[u];
    }
}

void dfs2(int x){
    int u;
    for(int i=head[x];i;i=nxt[i]){
        u=to[i];ans[u]=ans[x]+1+(double)(siz[x]-siz[u]-1)/2;
        dfs2(u);
    }
}

int main(){
    n=rd();int x;
    for(int i=2;i<=n;i++)
        x=rd(),add(x,i);
    ans[1]=1.0;dfs1(1);dfs2(1);
    for(int i=1;i<=n;i++) printf("%.8lf ",ans[i]);
    return 0;
}

CF696B Puzzles(期望dp)

标签:+=   etc   problem   tps   mat   char   cpp   ref   dfs   

原文地址:https://www.cnblogs.com/sdfzsyq/p/10050817.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!