• CodeForces 696B Puzzles


    思维,简单树$dp$。

    首先计算出每一个子树包含多少个节点,记为$f[i]$。然后就可以从$root$开始推出所有节点的期望了。

    现在已知$fa$节点的答案为$ans[fa]$,假设要计算$fa$的一个儿子$v$的期望,那么$ans[v]=ans[fa]+1.0+(f[fa]-f[v]-1)/2.0$。

    我画了一下样例,然后猜测了一下发现是对的......

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-8;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar(); x = 0;while(!isdigit(c)) c = getchar();
        while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar();  }
    }
    
    const int maxn=100010;
    double ans[maxn];
    vector<int>g[maxn];
    int n,f[maxn];
    
    void dfs(int x)
    {
        f[x]=0;
        for(int i=0;i<g[x].size();i++)
        {
            dfs(g[x][i]);
            f[x]=f[x]+f[g[x][i]];
        }
        f[x]++;
    }
    
    void get(int x)
    {
        for(int i=0;i<g[x].size();i++)
        {
            ans[g[x][i]]=ans[x]+1.0+1.0*(f[x]-f[g[x][i]]-1)/2.0;
            get(g[x][i]);
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=2;i<=n;i++)
        {
            int fa; scanf("%d",&fa);
            g[fa].push_back(i);
        }
        dfs(1);  ans[1]=1.0; get(1); 
        for(int i=1;i<=n;i++) printf("%.6lf ",ans[i]);
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    centos 给终端设快捷键
    centos 给鼠标右击添加 “打开终端” 菜单项
    centos 6.X 安装输入法
    centos U盘安装
    js的构造函数
    onresize的定义方式
    两个时间对比
    AMD和CMD的区别
    spring加载配置文件
    cglib代理
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5798395.html
Copyright © 2020-2023  润新知