【题解】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\n", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/twilight-sx/p/9822964.html

时间: 2024-10-31 12:35:06

【题解】CF#172(Div. 1) C.Game on Tree的相关文章

CF#247(Div. 2)部分题解

引言: 在软件项目中,Maven提供了一体化的类库管理系统,非常实用.但是,如果新增的类库jar在网络上无法获取到,如何在本地按照Maven的规则添加进来呢?本文将通过一个小例子展示新增过程. 背景介绍: 一个Maven管理的Java项目,提供一个系统级别的POM.xml,其中定义了整个项目使用的类库. 需求: 需要添加一个自定义的类库到当前项目中.假定当前的类库文件名为:abc.jar.. 如何将类库添加进来? 1.  找到当前Maven的Repository类库位置 一般默认情况下,在win

【题解】CF#474(Div.1+Div.2) H-Santa&#39;s Gift

好久没有写过数据结构题目了,果然还是太不自信.实际上就是要求统计一个式子: \(\sum (c[k]*p[k] - C)^{2}\) 拆开,分别统计和与平方和 \(co[k] * \sum p[k]^{2} - 2 * C * co[k] \sum p[k] + \sum C ^{2}\) 显然可以用树链剖分 + 线段树维护 平方和在区间 + 1的时候直接用 \((x + 1) ^ {2} = x^2 + 2 * x + 1\) 计算即可. 至于不同的口味的问题,我们给每个口味都开一线段树,动态

CF #371 (Div. 2) C、map标记

1.CF #371 (Div. 2)   C. Sonya and Queries  map应用,也可用trie 2.总结:一开始直接用数组遍历,果断T了一发 题意:t个数,奇变1,偶变0,然后与问的匹配. #include<bits/stdc++.h> #define max(a,b) a>b?a:b #define F(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF

CF #375 (Div. 2) D. bfs

1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多少个湖,然后输出. #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,s

CF #374 (Div. 2) D. 贪心,优先队列或set

1.CF #374 (Div. 2)   D. Maxim and Array 2.总结:按绝对值最小贪心下去即可 3.题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小. (1)优先队列 #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(

cf #254 (Div. 2)

a题 #include<stdio.h> #include<string.h> char c[101][101]; int main() { long n,m,i,j; scanf("%ld%ld",&n,&m); gets(c[0]); for(i=1;i<=n;i++) gets(c[i]); for(i=1;i<=n;i++) { for(j=0;j<m;j++) if(c[i][j]=='-') printf("

B. Mr. Kitayuta&#39;s Colorful Graph (CF #286 (Div. 2) 并查集)

B. Mr. Kitayuta's Colorful Graph time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the g

CF #374 (Div. 2) C. Journey dp

1.CF #374 (Div. 2)    C.  Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径,经过的点数要最多. #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,

CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有出现偶数次的数异或的值. 思路:容易想到,把区间内的所有的数都异或得到的是出现奇数次的数的值,然后再异或该区间内的所有出现过的数(每个数只统计一次),得到的ans了. 第一个问题:得到询问区间的