题解CF#172(Div. 1) C.Game on Tree

Posted twilight-sx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解CF#172(Div. 1) C.Game on Tree相关的知识,希望对你有一定的参考价值。

  感觉对期望也一无所知……(;′⌒`)╮(╯﹏╰)╭

  一直在考虑怎么dp,最后看了题解——竟然是这样的???【震惊】但是看了题解之后,觉得确实很有道理……

  我们可以考虑最后答案的组成,可以分开计算不同的点对于答案的贡献(期望具有线性性)。我们可以把这个染色的过程看做每一个节点均需要被染色,但只有第一个被染色的节点会消耗1点代价。这样我们就可以分别分析每个点对于答案产生贡献的概率,答案即为概率之和。而一个点会对答案产生影响的概率是多少?实际上这只与它到根的链上的节点是相关的,因为只要在染色它的祖先节点之前染色它,它就会对答案产生为1的贡献。

  那么当它和它的祖先均未被染色时,显然有选择任意节点的概率相等,显然有选择它的概率为 (frac{1}{dep[u]})(如果选择了其他节点,则该节点无法再产生贡献)。于是……这题就做完了。强啊!%%%

#include <bits/stdc++.h>
using namespace std;
#define maxn 200000
#define db double
int n, dep[maxn];
db ans;

int read()
{
    int x = 0, k = 1;
    char c; c = getchar();
    while(c < 0 || c > 9) { if(c == -) k = -1; c = getchar(); }
    while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = getchar();
    return x * k;
}

struct edge
{
    int cnp, to[maxn], last[maxn], head[maxn];
    edge() { cnp = 2; }
    void add(int u, int v)
    {
        to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++;
        to[cnp] = u, last[cnp] = head[v], head[v] = cnp ++;
    }
}E1;

void dfs(int u, int fa)
{
    for(int i = E1.head[u]; i; i = E1.last[i])
    {
        int v = E1.to[i];
        if(v == fa) continue;
        dep[v] = dep[u] + 1; dfs(v, u);
    }
}

int main()
{
    n = read();
    for(int i = 1; i < n; i ++)
    {
        int u = read(), v = read();
        E1.add(u, v);
    }
    dep[1] = 1; dfs(1, 0);
    for(int i = 1; i <= n; i ++) ans += (1.0 / (db) dep[i]);
    printf("%.10lf
", ans);
    return 0;
}

 

以上是关于题解CF#172(Div. 1) C.Game on Tree的主要内容,如果未能解决你的问题,请参考以下文章

CF1083(Round #526 Div. 1) 简要题解

AtCoder Beginner Contest 172 部分题解

题解 Codeforces Round #616 (Div. 2) (CF1291)

CF1169(div2)题解报告

CF1287 div2题解

BZOJ.3638.CF172 k-Maximum Subsequence Sum(模拟费用流 线段树)