• codeforces 696B B. Puzzles(树形dp+概率)


    题目链接:

    B. Puzzles

    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Barney lives in country USC (United States of Charzeh). USC has n cities numbered from 1 through n and n - 1 roads between them. Cities and roads of USC form a rooted tree (Barney's not sure why it is rooted). Root of the tree is the city number 1. Thus if one will start his journey from city 1, he can visit any city he wants by following roads.

    Some girl has stolen Barney's heart, and Barney wants to find her. He starts looking for in the root of the tree and (since he is Barney Stinson not a random guy), he uses a random DFS to search in the cities. A pseudo code of this algorithm is as follows:


    let starting_time be an array of length n
    current_time = 0
    dfs(v):
    current_time = current_time + 1
    starting_time[v] = current_time
    shuffle children[v] randomly (each permutation with equal possibility)
    // children[v] is vector of children cities of city v
    for u in children[v]:
    dfs(u)

    As told before, Barney will start his journey in the root of the tree (equivalent to call dfs(1)).

    Now Barney needs to pack a backpack and so he wants to know more about his upcoming journey: for every city i, Barney wants to know the expected value of starting_time[i]. He's a friend of Jon Snow and knows nothing, that's why he asked for your help.

    Input

    The first line of input contains a single integer n (1 ≤ n ≤ 105) — the number of cities in USC.

    The second line contains n - 1 integers p2, p3, ..., pn (1 ≤ pi < i), where pi is the number of the parent city of city number i in the tree, meaning there is a road between cities numbered pi and i in USC.

    Output

    In the first and only line of output print n numbers, where i-th number is the expected value of starting_time[i].

    Your answer for each city will be considered correct if its absolute or relative error does not exceed 10 - 6.

    Examples
    input
    7
    1 2 1 1 4 4
    output
    1.0 4.0 5.0 3.5 4.5 5.0 5.0 
    input
    12
    1 1 2 2 4 4 3 3 1 10 8
    output
    1.0 5.0 5.5 6.5 7.5 8.0 8.0 7.0 7.5 6.5 7.5 8.0 

    题意:

    给一棵有根树,dfs给这些节点编号,问每个节点编号的期望是多少?

    思路:

    在每个子树中,可以发现每个节点cur ,dp[cur]=dp[fa]+f(cur);
    f这个函数可以发现是把fa当根节点,得到的每个子节点的期望值,这个值跟这棵子树的节点数有关;反正我最后发现可以变成一个等差数列;最后变成了(num[fa]-num[cur]-1)/2+1;
    哈哈哈,反正就是一阵乱猜猜出来的;

    AC代码:
    #include <bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    
    typedef  long long LL;
    
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e18;
    const int N=3e6+10;
    const int maxn=3e6;
    const double eps=1e-10;
    
    int n,num[N];
    double dp[N];
    vector<int>ve[N];
    
    int cnt = 0;
    void dfs(int cur,int fa)
    {
        num[cur]=1;
        int len = ve[cur].size();
        For(i,0,len-1)
        {
            int y=ve[cur][i];
            dfs(y,cur);
            num[cur]+=num[y];
        }
    }
    void dfs1(int cur,int fa)
    {
        int len=ve[cur].size();
        dp[cur]=dp[fa]+(num[fa]-num[cur]-1)*1.0/2+1;
        For(i,0,len-1)dfs1(ve[cur][i],cur);
    }
    int main()
    {
            read(n);
            For(i,2,n)
            {
                int x;
                read(x);
                ve[x].push_back(i);
            }
            dp[0]=0;
            num[0]=n+1;
            dfs(1,0);
            dfs1(1,0);
            For(i,1,n)printf("%.10lf ",dp[i]);
            return 0;
    }
  • 相关阅读:
    作业要求 20181030-1 Alpha发布用户使用报告
    Scrum立会报告+燃尽图(Beta阶段第二周第二次)
    Scrum立会报告+燃尽图(Beta阶段第二周第一次)
    20181113-3 Beta阶段贡献分配规则
    20181113-1 版本控制报告
    Scrum立会报告+燃尽图(Beta阶段第七次)
    Scrum立会报告+燃尽图(Beta阶段第六次)
    Scrum立会报告+燃尽图(Beta阶段第五次)
    Scrum立会报告+燃尽图(Beta阶段第四次)
    Scrum立会报告+燃尽图(Beta阶段第三次)
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5674617.html
Copyright © 2020-2023  润新知