《CF280C Game on Tree》

题目描述

给定一棵有根树,结点编号从 1 到 n。根结点为 1 号结点。

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

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

输入格式

第一行,一个正整数 n 表示结点数量。

接下来 n−1 行每行两个数,表示树上的一条连接 ai​ 与 bi​ 的边 (ai​,bi​)。

保证给定的数据是一棵树。

输出格式

输出一个实数,表示期望操作次数。答案误差在 10−6 之内则认为正确。

显示翻译

题意翻译

输入输出样例

输入 #1复制

复制代码
2
1 2

输出 #1复制

复制代码
1.50000000000000000000

输入 #2复制

复制代码
3
1 2
1 3

输出 #2复制

复制代码
2.00000000000000000000

说明/提示

样例解释

在第一个样例中,有两种情况:

一种是直接删除根(即 1 号结点),另一种是先删去 2 号结点,再删除 1 号结点。

操作次数的期望是 1×21​+2×21​=1.5。

在第二个样例中,情况更为复杂。其中有两种情况会将问题转化成第一个样例,而剩下的一种情况会一次全部删除。

操作次数的期望是 1×31​+(1+1.5)×32​=31​+35​=2。

数据范围

1≤n≤105,1≤ai​,bi​≤n,ai​=bi​

代码实现:

cpp 复制代码
#include<stdio.h>
const int N=100005,M=200005;
int n,c;
int h[N],v[M],nxt[M],d[N];
double res;
inline void add(int x,int y){
	nxt[++c]=h[x],h[x]=c,v[c]=y;
}
void dfs(int x,int fa){
	d[x]=d[fa]+1;
	for(int i=h[x];i;i=nxt[i]){
		int y=v[i];
		if(y==fa)
			continue;
		dfs(y,x);
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y),add(y,x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++)
		res+=1.0/d[i];
	printf("%.20f\n",res);
	return 0;
}
相关推荐
vibecoding日记2 天前
双非如何快速入职字节等大厂大模型?真实案例分析:推理优化和投机解码
算法·求职·大模型工程师
yszaygr21382 天前
Verilog参数化游程编码RLE模块
算法
望易2 天前
刚设计的大模型架构-双域耦合认知框架
算法·架构
复杂网络2 天前
多个 Claude Code 与多个 Codex 协同工作:设计与实现方案
算法
HjhIron2 天前
面试常客:字符串算法从入门到进阶
算法·面试
吴佳浩3 天前
DeepSeek DSpark:Confidence-Scheduled Speculative Decoding 技术解析
人工智能·算法·deepseek
触底反弹3 天前
🧠 搞懂 Token,才算真正入门大模型——从分词原理到 Embedding 语义实战
javascript·人工智能·算法
vivo互联网技术3 天前
ICLR 2026 | 基于后验采样的图像恢复方法LearnIR:人脸去阴影、去雾
人工智能·算法·aigc
浮生望3 天前
JS字符串与回文算法:从包装类到双指针的面试进阶之路
javascript·算法