Codeforces Round #362 (Div. 2) D 树形dp
来源:互联网 发布:导航端口修改工具 编辑:程序博客网 时间:2024/06/05 22:59
链接:戳这里
Some girl has stolen Barney's heart, and Barney wants to find her. He starts looking for in the root of the tree and (since he is Barney Stinson not a random guy), he uses a random DFS to search in the cities. A pseudo code of this algorithm is as follows:
let starting_time be an array of length n
current_time = 0
dfs(v):
current_time = current_time + 1
starting_time[v] = current_time
shuffle children[v] randomly (each permutation with equal possibility)
// children[v] is vector of children cities of city v
for u in children[v]:
dfs(u)
As told before, Barney will start his journey in the root of the tree (equivalent to call dfs(1)).
Now Barney needs to pack a backpack and so he wants to know more about his upcoming journey: for every city i, Barney wants to know the expected value of starting_time[i]. He's a friend of Jon Snow and knows nothing, that's why he asked for your help.
Input
The first line of input contains a single integer n (1 ≤ n ≤ 105) — the number of cities in USC.
The second line contains n - 1 integers p2, p3, ..., pn (1 ≤ pi < i), where pi is the number of the parent city of city number i in the tree, meaning there is a road between cities numbered pi and i in USC.
Output
In the first and only line of output print n numbers, where i-th number is the expected value of starting_time[i].
Your answer for each city will be considered correct if its absolute or relative error does not exceed 10 - 6.
Examples
input
7
1 2 1 1 4 4
output
1.0 4.0 5.0 3.5 4.5 5.0 5.0
input
12
1 1 2 2 4 4 3 3 1 10 8
output
1.0 5.0 5.5 6.5 7.5 8.0 8.0 7.0 7.5 6.5 7.5 8.0
题意:
一个树,dfs遍历子树的顺序是随机的。所对应的子树的dfs序也会不同。输出每个节点的dfs序的期望
思路:
分析一颗子树:
当前已知节点1的期望为1.0 ->anw[1]=1.0
需要通过节点1递推出节点2、4、5的期望值
1的儿子分别是2、4、5,那么dfs序所有可能的排列是6种:
1:1-2-4-5 (2、4、5节点的儿子没有写出)
2:1-2-5-4
3:1-4-2-5
4:1-4-5-2
5:1-5-2-4
6:1-5-4-2
计算节点2的期望值得时候,当节点2的前面已经排列了num个点,那么节点2的dfs序就要增加num
所以anw[2]的计算分为两部分,第一部分是:anw[2]=anw[1]+1 (节点1通过1步直接到达儿子2、4、5)
第二部分是:当节点1到达节点2的时候贡献是0,种类分别对应(1、2)
当先到达节点4后到节点2的时候贡献(size(4)+size(4)+szie(5)),种类分别对应(3、4)
当先到达节点5后到节点2的时候贡献(size(5)+size(5)+size(4)),种类分别对应(5、6)
而所有的排列对于的概率都是1/6,所以第二部分的贡献就是(0+size(4)*3+size(5)*3)/6 = (size(4)+size(5))/2
仔细推理几颗子树之后:发现anw[v]=anw[u]+1.0+(sz[u]-sz[v]-1)/2.0。
anw[u]+1.0对应第一部分 (sz[u]-sz[v]-1)/2.0 表示的是当前能排在节点v前面的u的儿子的总数 * 0.5
对比1-6的6种排列,任意儿子a、b ,满足a在b前面的概率是0.5
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<iomanip>#include<cmath>#define mst(ss,b) memset((ss),(b),sizeof(ss))#define maxn 0x3f3f3f3f#define MAX 1000100///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;typedef unsigned long long ull;#define INF (1ll<<60)-1using namespace std;int n;struct edge{ int v,next;}e[500100];int head[100100],tot=0;void Add(int u,int v){ e[tot].v=v; e[tot].next=head[u]; head[u]=tot++;}int sz[100100];void DFS(int u,int fa){ sz[u]=1; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(v==fa) continue; DFS(v,u); sz[u]+=sz[v]; }}double anw[100100];void DFS1(int u,int fa){ for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(v==fa) continue; anw[v]=anw[u]+1.0+(sz[u]-sz[v]-1)*1.0/2.0; DFS1(v,u); }}int main(){ mst(head,-1); scanf("%d",&n); for(int i=2;i<=n;i++){ int x; scanf("%d",&x); Add(x,i); Add(i,x); } DFS(1,0); anw[1]=1.0; DFS1(1,0); for(int i=1;i<=n;i++) printf("%.2f ",anw[i]); return 0;}
- Codeforces Round #362 (Div. 2) D 树形dp
- Codeforces Round #362 (Div. 2) D Puzzles(树形dp)
- Codeforces Round #263 (Div. 2)D(树形DP)
- Codeforces Round #277 (Div. 2) D题 树形dp
- Codeforces Round #277 (Div. 2) D. Valid Sets (树形DP)
- Codeforces Round #135 (Div. 2) D 树形dp
- Codeforces Round #263 (Div. 2) D 树形dp
- Codeforces Round #384 (Div. 2)D(树形dp,dfs)
- Codeforces Round #275 (Div. 1)D(树形DP)
- Codeforces Round #302 (Div. 1)D. Road Improvement 树形dp
- Codeforces Round #273 (Div. 2)D dp
- Codeforces Round #358 (Div. 2) D dp
- Codeforces Round #277 (Div. 2)D(树形DP计数类)
- Codeforces Round #135 (Div. 2) - D. Choosing Capital for Treeland(dfs / 树形DP)
- Codeforces Round #384(Div. 2)D. Chloe and pleasant prizes【树形dp】
- Codeforces Beta Round #14 (Div. 2) D. Two Paths 树形dp
- Codeforces Round #362 (Div. 2) D. Puzzles(概率dp)
- Codeforces Round #362 (Div. 2) D Puzzles (DP)
- Java逻辑运算符
- IntentFilter的匹配规则
- oracle实现id自增和设置主键
- Sybase 部分SQL语句介绍
- 简单自动匹配下拉文字
- Codeforces Round #362 (Div. 2) D 树形dp
- 用Webpack构建Vue
- ARM 内核SP,LR,PC寄存器
- Android工具类之单位转换类
- 新浪开发平台实现分享
- Eclipse 反编译插件 —— Java Class Decompiler
- ios developer tiny share-20160715
- Android中关于RecycleView的使用,代替ListView,可以提高效率
- css input 如何去掉点击后出现的边框