HDOJ 5425 Rikka with Tree II
2015-09-01 14:14
288 查看
和上次的上海邀请赛的那个dp优化技巧类似。都是考虑double精度,来减少枚举次数。。。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 100005; const int maxm = 200005; struct Edge { int v; Edge *next; }*H[maxn], E[maxm], *edges; double a[maxn]; double res[maxn]; double res2[maxn]; int n; void init() { edges = E; for(int i = 0; i <= n; i++) H[i] = 0; } void addedges(int u, int v) { edges->v = v; edges->next = H[u]; H[u] = edges++; } void dfs(int u, int fa, int dep) { a[u] = dep; for(Edge *e = H[u]; e; e = e->next) if(e->v != fa) dfs(e->v, u, dep + 1); } void work() { for(int i = 2; i <= n; i++) { int fa; scanf("%d", &fa); addedges(i, fa); addedges(fa, i); } dfs(1, 1, 0); sort(a+1, a+n+1); double ans = 0; if(n <= 40) { for(int i = 1; i <= n; i++) for(int j = 1; j < i; j++) { double t = (a[i] + 1) * (a[j] + 1) / (a[i] + a[j] + 2); ans += t * res2[j-1] / (res2 - 1 - n); } } else { for(int i = 1; i <= n; i++) for(int j = max(1, i - 40); j < i; j++) { double t = (a[i] + 1) * (a[j] + 1) / (a[i] + a[j] + 2); ans += t * res[n-j+1]; } } printf("%.6f\n", ans); } int main() { res[0] = res2[0] = 1; for(int i = 1; i <= 70; i++) res[i] = res[i-1] / 2, res2[i] = res2[i-1] * 2; while(scanf("%d", &n) != EOF) { init(); work(); } return 0; }
相关文章推荐
- 基于W5500的嵌入式TFTP服务器实现
- 使用timer做计时器的Demo
- iOS电脑安装Pods
- fdupes:Linux 中查找并删除重复文件的命令行工具
- 精通Hibernate——Hibernate的映射类型
- Xcode打包踩过的那些坑
- 训犬日志--狗狗定点排便
- js核心--------作用域链了解
- Android源码之简单定时器
- 翻转二叉树节点数据
- 如何利用C生成.so供Mono调用
- ListView滑动删除 ,仿腾讯QQ
- 忙是治疗一切神经病的良药
- 图片的轮转
- 改进的日期插件
- MySQL连接数超过限制的解决方法
- asp.net 时间的显示
- U-boot的bootargs环境变量详解
- WCF理论 【转载】
- 动态添加行,删除行