【Codeforces 696B】【JZOJ 4647】寻找
2016-07-17 12:28
543 查看
Description
他们度蜜月的地方是一棵树,共有N个节点,Bob会使用下列DFS算法对该树进行遍历。starting_time是一个容量为n的数组 current_time = 0 dfs(v): current_time = current_time + 1 starting_time[v] = current_time 将children[v]的顺序随机排列 (每个排列的概率相同) // children[v]v的直接儿子组成的数组 for u in children[v]: dfs(u)
1是这棵树的根,Bob会从1出发,即运行dfs(1),现在他想知道每个点starting_time的期望值。
Analysis
设当前要算v的期望,已经算出了v的father的期望,把那些排列写出来,仔细观察,可以将排列按v在当前其兄弟的列表中的出现位置分类。设v及其兄弟共有n个,sum表示v的兄弟的大小和。可以得出这样一个式子
Ans[v]=∑k=0n−1k(n−2)!sum+f[v]+1
化简之后就成了
Ans[v]=Ans[father]+1+sum/2
Code
#include<cstdio> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define efo(i,v) for(int i=last[v];i;i=next[i]) using namespace std; const int N=100010,M=N*2; int n,tot,to[M],next[M],last ,size ; double f ; void link(int u,int v) { to[++tot]=v,next[tot]=last[u],last[u]=tot; } void dfs1(int v,int from) { size[v]=1; efo(i,v) { int u=to[i]; if(u==from) continue; dfs1(u,v); size[v]+=size[u]; } } void dfs(int v,int from) { efo(i,v) { int u=to[i]; if(u==from) continue; f[u]=f[v]+1+(size[v]-1-size[u])/2.0; dfs(u,v); } } int main() { int x; scanf("%d",&n); fo(i,2,n) { scanf("%d",&x); link(i,x),link(x,i); } dfs1(1,0); f[1]=1; dfs(1,0); fo(i,1,n) printf("%.1lf ",f[i]); return 0; }
相关文章推荐
- Python 学习(一)
- Spark学习(2)
- MySQL锁系列1
- Qt中将QString转换为char *或者相反
- ci框架修改默认控制器
- Multivariate Linear Regression的参数估计
- Homework-linux
- ci框架url传递参数出现:The URI you submitted has disallowed characters
- Leetcode 345. Reverse Vowels of a String (Easy) (cpp)
- python多线程下载
- android studio 2.1去标题栏方法
- MYSQL分页limit速度太慢优化方法
- Python学习进程(2)Python环境的搭建
- Android Studio的no debuggable applications问题
- Java多线程 之 lock与condition的使用(十四)
- AudioRecord实现"助听器"
- MySQL join buffer使用
- My97DatePicker控件显示时分秒
- Java 匿名类不能拥有一个构建器
- 2016.7.16 夏令营 Day9