标签:+= etc problem tps mat char cpp ref dfs
比较有意思的一道题。首先假如这个点\(x\)只有\(1\)个儿子\(u\),那么显然可得\(dp[u]=dp[x]+1\)。继续如果多加一个儿子\(p\),那么\(p\)在\(u\)前面的概率就是\(1/2\),也就是说\(p\)对于\(u\)的答案有\(1/2\)的可能产生贡献,而产生的贡献为\(siz[p]\),那么继续归纳下去,就可以得出转移方程。\(dp[u]=dp[x]+1+(siz[x]-siz[u]-1)/2\)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN = 100005;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {f=ch==‘-‘?0:1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
return f?x:-x;
}
int n,head[MAXN],cnt,to[MAXN],nxt[MAXN],siz[MAXN];
double ans[MAXN];
inline void add(int bg,int ed){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
}
void dfs1(int x){
int u;siz[x]=1;
for(int i=head[x];i;i=nxt[i]){
u=to[i];dfs1(u);
siz[x]+=siz[u];
}
}
void dfs2(int x){
int u;
for(int i=head[x];i;i=nxt[i]){
u=to[i];ans[u]=ans[x]+1+(double)(siz[x]-siz[u]-1)/2;
dfs2(u);
}
}
int main(){
n=rd();int x;
for(int i=2;i<=n;i++)
x=rd(),add(x,i);
ans[1]=1.0;dfs1(1);dfs2(1);
for(int i=1;i<=n;i++) printf("%.8lf ",ans[i]);
return 0;
}
标签:+= etc problem tps mat char cpp ref dfs
原文地址:https://www.cnblogs.com/sdfzsyq/p/10050817.html