CF280C Game on Tree

CF280C Game on Tree

题解

题意

给定一棵有根树,结点编号从 11nn。根结点为 11 号结点。

对于每一次操作,等概率的选择一个尚未被删去的结点并将它及其子树全部删去。当所有结点被删除之后,游戏结束;也就是说,删除11 号结点后游戏即结束。

要求求出删除所有结点的期望操作次数。

n105n \le 10 ^ 5

解法

如果设fif_i表示每个点的权值,权值的范围显然只有0011, 答案其实就是求E(fi)E(\sum f_i),根据期望的线性性,可以得出E(fi)=E(fi)E(\sum f_i) = \sum E(f_i), 考虑每个点的期望其实就是这个点被选中的概率,如果这个点被选到,显然一定是在其祖先选到之前,每个节点有depthi1depth_i - 1个祖先,答案就是i=1n1depthi\sum_{i = 1} ^ n \frac{1}{depth_i}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int n;

int cnt, head[N];

struct edge
{
int to, nxt;
edge(int v = 0, int x = 0) : to(v), nxt(x) {}
};

edge e[N << 1];

void add(int u, int v)
{
e[++cnt] = edge(v, head[u]); head[u] = cnt;
e[++cnt] = edge(u, head[v]); head[v] = cnt;
}

int depth[N];

void dfs(int x, int fa)
{
depth[x] = depth[fa] + 1;
for(int i = head[x]; i; i = e[i].nxt)
{
int v = e[i].to;
if(v == fa)continue;
dfs(v, x);
}
}

int main()
{
scanf("%d", &n);
for(int i = 1; i < n; i++)
{
int x, y;
scanf("%d%d", &x, &y);
add(x, y);
}
dfs(1, 0);
double ans = 0;
for(int i = 1; i <= n; i++)
ans += 1.0 / depth[i];
printf("%.6lf", ans);
return 0;
}
作者

Jekyll_Y

发布于

2022-11-02

更新于

2023-03-02

许可协议

评论