zoukankan      html  css  js  c++  java
  • 【题解】CF#280 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;
    }
  • 相关阅读:
    创意:网络族谱
    排列组合的要点
    创意:人生记录
    纽康悖论谜题
    发财的要点
    c#4.0协变逆变的理解
    关于开发自我训练课程
    反对继承
    远离疲倦,告别非理性思维
    中国软件正版化的理想模型
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/9822964.html
Copyright © 2011-2022 走看看