CF280C Game on Tree
题目链接 : CF280C Game on Tree
题意 : 给定一棵n个节点的树T 根为一(我咕的翻译漏掉了。。。)
每次随机选择一个未被删除的点 并将它的子树删除
求删整棵树的期望步数
n ∈ [1, 1e5]
裸期望问题
考虑贡献
如果要避开一个点对其他点的影响关系【蒟蒻觉得这是期望问题最重要的点
一个点的贡献就只看它自己 不看它的子树
这时每个点如果对结果有贡献 那么就是选中了它 它还没被删
这个的概率就是它上面的节点(父亲、各辈祖宗) 都没被删
由此得
E = Σa P(a被选择时没被删) * 1 = Σa (1 / dep[a])
附上代码:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 const int N = 1e5 + 5; 5 int n, k; 6 int dep[N]; 7 struct Edge{ 8 int v, next; 9 }edge[N << 1]; 10 int head[N], esize; 11 double e; 12 13 inline void addedge(int x, int y){ 14 edge[++esize] = (Edge){y, head[x]}; 15 head[x] = esize; 16 } 17 18 void calc(int x, int fa){ 19 dep[x] = dep[fa] + 1; 20 for(int i = head[x], vv; i != -1; i = edge[i].next){ 21 vv = edge[i].v; 22 if(vv == fa) continue; 23 calc(vv, x); 24 } 25 } 26 27 int main(){ 28 scanf("%d", &n); 29 for(int i = 1; i <= n; i++) head[i] = -1; 30 for(int i = 1, x, y; i < n; i++){ 31 scanf("%d%d", &x, &y); 32 addedge(x, y); addedge(y, x); 33 } 34 dep[1] = 0; 35 calc(1, 1); 36 for(int i = 1; i <= n; i++) 37 e += (1.0 / (1.0 * dep[i])); 38 printf("%lf", e); 39 return 0; 40 }