《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;
}
相关推荐
L_09071 天前
【C++】高阶数据结构 -- 红黑树
数据结构·c++
A_nanda1 天前
c# MOdbus rto读写串口,如何不相互影响
算法·c#·多线程
代码雕刻家1 天前
2.4.蓝桥杯-分巧克力
算法·蓝桥杯
Ulyanov1 天前
顶层设计——单脉冲雷达仿真器的灵魂蓝图
python·算法·pyside·仿真系统·单脉冲
智者知已应修善业1 天前
【查找字符最大下标以*符号分割以**结束】2024-12-24
c语言·c++·经验分享·笔记·算法
划破黑暗的第一缕曙光1 天前
[数据结构]:5.二叉树链式结构的实现1
数据结构
91刘仁德1 天前
c++类和对象(下)
c语言·jvm·c++·经验分享·笔记·算法
青桔柠薯片1 天前
数据结构:单向链表,顺序栈和链式栈
数据结构·链表
diediedei1 天前
模板编译期类型检查
开发语言·c++·算法
阿杰学AI1 天前
AI核心知识78——大语言模型之CLM(简洁且通俗易懂版)
人工智能·算法·ai·语言模型·rag·clm·语境化语言模型