CF697D 树形DP
来源:互联网 发布:golang flag 用法 编辑:程序博客网 时间:2024/06/16 13:05
题目链接:http://codeforces.com/contest/697/problem/D
给出一颗树的描述,从根节点开始,以DFS序遍历。每次随机走向当前节点的儿子节点,没有子节点的时候就回溯。问遍历到树中每个点的期望步数。
考虑某一层DFS,假设我们已经求出该层根节点Root的答案ans[Root]。求该层x节点的答案。对于其他的节点有1/2的概率会排在该节点前面,对ans[x]的贡献就为该节点u的子树大小的1/2。那么ans[x] = ans[Root] + (size[Root]-size[x]-1]/2 + 1。
即 ans[x] = ans[Root] + (size[Root]-size[x])/2 + 1/2。
#include<bits/stdc++.h>using namespace std;const int maxn = 1e5+10;int head[maxn], tot;int sz[maxn];struct Edge{ int to, nx; Edge(){} Edge(int t){ to = t; }}e[2*maxn+1];double dp[maxn];int dfs(int u, int pre){ sz[u] = 1; for (int k = head[u]; k != -1; k = e[k].nx){ int to = e[k].to; if (to == pre) continue; sz[u] += dfs(to, u); } return sz[u];}void getans(int u, int pre){ for (int k = head[u]; k != -1; k = e[k].nx){ int to = e[k].to; if (to == pre) continue; dp[to] = dp[u] + 0.5 + (sz[u]-sz[to])*(1.0/2); getans(to, u); }}void addEdge(int from, int to){ e[++tot] = Edge(to); e[tot].nx = head[from]; head[from] = tot;}int main(){ memset(head, -1, sizeof(head)); tot = 0; int n; cin >> n; for (int i = 2; i <= n; i++){ int to; cin >> to; addEdge(i, to); addEdge(to, i); } dfs(1, 1); dp[1] = 1.0; getans(1, 1); for (int i = 1; i <= n; i++) printf("%.1f", dp[i]), printf((i==n ? "\n" : " ")); return 0;}
阅读全文
0 0
- CF697D 树形DP
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形DP
- 树形DP
- 树形DP
- 树形dp
- 树形dp
- 树形dp
- 树形dp
- 树形DP
- 树形DP
- 树形DP
- 树形DP
- 写给大一大二大三还在迷惘中的学生
- spring aop+queue+多线程轮询消费实现方法拦截后的异步处理
- leetcode question3.Longest Substring Without Repeating Characters
- multiple definition of 问题解决方法
- iOS项目生成静态库文件(.a)
- CF697D 树形DP
- 微信公众帐号开发教程第4篇-----开发模式启用及接口配置Java
- 动态规划:HDU1069-Monkey and Banana
- 初学结构体
- vijos1264 神秘的咒语
- redis setNX 锁来实现防止重复提交的
- ActiveMQ学习笔记(1)——JMS的概念
- java SE 数据类型
- Spring boot中mongodb的使用