zoukankan      html  css  js  c++  java
  • CodeForces

    传送门:D - Puzzles

    题意:在一个图中,从1开始dfs,求每一个点到达的期望;

     

    思路:(下面是队长写的)

    首先求的是到每一个点的步数的期望.

    记fa( u ) = v, son( v )表示v的儿子的集合,

    z是son(v)中的点,其中 z != u ,  sum[z] 为 z 的子树的大小, p( z )表示z比u先访问到的概率;

    那么可以发现对于u来说 ans[u] = ans[v] + 1 + x;

    现在我要来算这个x, 如果 son(v).size == 1, 那么x为0;

    否则能对u造成影响的就是son(v)中不是u的那些点,

    以z为例, 如果z先于u访问到,那么到达u的步数就会加上sum[z], 那么 x += sum[z] * p(z);          

    可以发现这样一个规律对于son(v)任意一种排列a,都可以发现一种对应排列b,满足a和b中只有u和z的位置对换.而且u和v不可能同时被访问或者其中一个不被访问,那么可以得到p(z) = 0.5; 就是 x += sum[z] * 0.5;

    那么x就可以算出来了: for(auto it : son[v]) x += sum[it] * 0.5;

    时间复杂度O(n);

    所以下面的ac代码中,dfs1()就是求每一个点的sum值,通过类似前缀和的思想;

              get1()就是求ans;

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    using namespace std;
    
    const int maxn = 100007;
    
    int n,sum[maxn];
    vector<int>mp[maxn];
    double ans[maxn];
    void init(){
        for(int i=1;i<=n;i++)
            mp[i].clear();
        memset(ans,0,sizeof(ans));
        memset(sum,0,sizeof(sum));
    }
    void dfs1(int d)
    {
        sum[d] = 1;
        for(int  t=0; t < mp[d].size(); t++)
        {
            int to = mp[d][t];
            dfs1(to);
            sum[d] += sum[to];
        }
    } 
    void get1(int d)
    {
        for(int t=0; t<mp[d].size(); t++)
        {
            int to = mp[d][t];
            ans[to] = ans[d] + 1 + (sum[d]-sum[to]-1) * 0.5;
            get1(to);
        }
    }
    int main(){
      //  freopen("in","r",stdin);
        while(~scanf("%d", &n))        
        {
            init();
            for(int i=2; i<=n; i++)
            {
                int x;
                scanf("%d",&x);
                mp[x].push_back(i);
            }
            dfs1(1);
            ans[1] = 1.0;
            get1(1);
            for(int i=1; i<=n; i++)
            {
                printf("%.1f%c", ans[i], i==n?'
    ':' ');
            }
        }
        return 0;
    }

     

  • 相关阅读:
    C语言常用函数-ispunct()判断字符是否为标点符号函数
    C语言常用函数-isupper()判断字符是否为大写英文字母函数
    C语言常用函数-isprint()判断字符是否为可打印字符(含空格)函数
    C语言常用函数-islower()判断字符是否为小写英文字母函数
    C语言常用函数-isgraph()判断字符是否为除空格外的可打印字符函数
    get请求多参数循环拼接
    数据库字段转驼峰命名
    React钩子函数问题,解决父组件实时更新子组件的值
    关于react 父级组件更新数据触发子组件更新渲染问题
    Jquery的ajax 方法
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8584025.html
Copyright © 2011-2022 走看看