您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: