【codeforces 696B】 Puzzles
http://codeforces.com/problemset/problem/696/B (题目链接)
题意
给出一棵树,随机dfs遍历这棵树,求解每个节点的期望dfs序。
Solution
考虑对于节点u,其某个儿子节点v的期望是多少。
首先,节点u的儿子的dfs的顺序是其儿子数son[x]的全排列。考虑在排列中有多少个节点在v的前面,不妨设x排在v的前面,那么满足的排列数为:${P_n^{n-2}}$,于是x对v的期望的贡献为:$${\frac{P_n^{n-2}×size[x]} {P_n^n}=\frac{1}{2}×size[x]}$$
因为节点u的每一个节点都会对v产生贡献,再算上v自己的贡献,所以v的期望:
$${f_v=\frac{size_u-1-size[v]}{2}+1+f[u]}$$
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // codeforces696B #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 1<<30 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=100010; struct edge { int to,next;}e[maxn<<1]; int head[maxn],size[maxn],n,cnt; double f[maxn]; void link( int u, int v) { e[++cnt]=(edge){v,head[u]};head[u]=cnt; } void dfs( int x) { size[x]=1; for ( int i=head[x];i;i=e[i].next) { dfs(e[i].to); size[x]+=size[e[i].to]; } } void dp( int x) { for ( int i=head[x];i;i=e[i].next) { f[e[i].to]=( double )(size[x]-1-size[e[i].to])/2+1+f[x]; dp(e[i].to); } } int main() { scanf ( "%d" ,&n); for ( int x,i=2;i<=n;i++) { scanf ( "%d" ,&x); link(x,i); } dfs(1); f[1]=1;dp(1); for ( int i=1;i<=n;i++) printf ( "%.6lf " ,f[i]); return 0; } |
This passage is made by MashiroSky.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步