Luogu 4284 [SHOI2014]概率充电器
BZOJ 3566
树形$dp$ + 概率期望。
每一个点的贡献都是$1$,在本题中期望就等于概率。
发现每一个点要通电会在下面三件事中至少发生一件:
1、它自己通电了。
2、它的父亲给它通电了。
3、它的儿子给它通电了。
那么我们设$f_i$表示它的父亲给它通电的概率,$g_i$表示它的子树中给它通电的概率,那么最后的答案$\sum_{i = 1}^{n}f_i + g_i - f_i * g_i = \sum_{i = 1}^{n}1 - (1 - f_i) * (1 - g_i)$。
感觉好麻烦,直接把$f_i$和$g_i$设成不通电的概率好了。
先考虑计算$g$。
假设每个点$i$自己通电的概率是$a_i$,一条连接着$x$和$y$的边通电的概率是$val(x, y)$,那么$g_x = (1 - a_x)\prod_{y \in son(x)}(g_y + (1 - g_y) * (1 - val(x, y)))$。
因为如果一个点不从自己的子树中得到电,那么它自己一定没有电,然后对于每一个儿子,要么不通电,要么通了电但是这条边是不通电的,电量传递不上来。
然后考虑计算$f$,对于一对父子关系的点$(x, y)$,我们发现要么$x$不带电,要么$x$带了电但是这条边传递不过来,那么$x$不带电的概率$P = \frac{f_x * g_x}{g_y + (1 - g_y) * (1 - val(x, y))}$,
这时候我们默认$y$是不带电的,但是我们在计算$g_x$的时候多算了$y$的贡献,所以要除掉,然后$f_y = P + (1 - P) * (1 - val(x, y))$。
时间复杂度$O(n)$。
Code:
#include <cstdio>
#include <cstring>
using namespace std;
typedef double db; const int N = 5e5 + ; int n, tot = , head[N];
db a[N], f[N], g[N]; struct Edge {
int to, nxt;
db val;
} e[N << ]; inline void add(int from, int to, db val) {
e[++tot].to = to;
e[tot].val = val;
e[tot].nxt = head[from];
head[from] = tot;
} inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} void dfs1(int x, int fat) {
g[x] = - a[x];
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
dfs1(y, x);
g[x] *= (g[y] + ( - g[y]) * ( - e[i].val));
}
} void dfs2(int x, int fat, int inEdge) {
if(!fat) f[x] = 1.0;
else {
db p = g[fat] * f[fat] / (g[x] + ( - g[x]) * ( - e[inEdge].val));
f[x] = p + ( - p) * ( - e[inEdge].val);
} for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
dfs2(y, x, i);
}
} int main() {
// freopen("2.in", "r", stdin); read(n);
for(int x, y, v, i = ; i < n; i++) {
read(x), read(y), read(v);
db val = 1.0 * v / 100.0;
add(x, y, val), add(y, x, val);
}
for(int i = ; i <= n; i++) {
int v; read(v);
a[i] = 1.0 * v / 100.0;
} dfs1(, );
dfs2(, , ); /* for(int i = 1; i <= n; i++)
printf("%f ", f[i]);
printf("\n");
for(int i = 1; i <= n; i++)
printf("%f ", g[i]);
printf("\n"); */ db ans = ;
for(int i = ; i <= n; i++)
ans += ( - g[i] * f[i]); printf("%.6f\n", ans);
return ;
}
Luogu 4284 [SHOI2014]概率充电器的更多相关文章
- luogu P4284 [SHOI2014]概率充电器 期望 概率 树形dp
LINK:概率充电器 大概是一个比较水的题目 不过有一些坑点. 根据期望的线性性 可以直接计算每个元件的期望 累和即为答案. 考虑统计每一个元件的概率的话 那么对其有贡献就是儿子 父亲 以及自己. 自 ...
- 【题解】Luogu P4284 [SHOI2014]概率充电器
原题传送门 我们知道,每个电器充电对充电电器数的贡献都是相等的1,所以若第\(i\)个电器有\(p_i\)的概率充电时 \[E=\sum_{i=1}^np_i\] 我们考虑如何求\(p_i\),根据树 ...
- P4284 [SHOI2014]概率充电器
P4284 [SHOI2014]概率充电器 今天上课讲到的题orz,第一次做这种上下搞两次dp的题. g[i]表示i的子树(包括i)不给i充电的概率. f[i]表示i的父亲不给i充电的概率. g[]可 ...
- BZOJ 3566: [SHOI2014]概率充电器( 树形dp )
通过一次dfs求出dp(x)表示节点x考虑了x和x的子树都没成功充电的概率, dp(x) = (1-p[x])π(1 - (1-dp[son])*P(edge(x, son)).然后再dfs一次考虑节 ...
- BZOJ 3566: [SHOI2014]概率充电器 [树形DP 概率]
3566: [SHOI2014]概率充电器 题意:一棵树,每个点\(q[i]\)的概率直接充电,每条边\(p[i]\)的概率导电,电可以沿边传递使其他点间接充电.求进入充电状态的点期望个数 糖教题解传 ...
- BZOJ3566: [SHOI2014]概率充电器 树形+概率dp
3566: [SHOI2014]概率充电器 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1888 Solved: 857[Submit][Stat ...
- 洛谷 P4284 [SHOI2014]概率充电器 解题报告
P4284 [SHOI2014]概率充电器 题目描述 著名的电子产品品牌SHOI 刚刚发布了引领世界潮流的下一代电子产品-- 概率充电器: "采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- 【BZOJ 3566】 3566: [SHOI2014]概率充电器 (概率树形DP)
3566: [SHOI2014]概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线能否通电 ...
- BZOJ3566 SHOI2014 概率充电器 【概率DP】
BZOJ3566 SHOI2014 概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能 ...
随机推荐
- html页面中如何设置当光标移到一个固定区域时其形状变成手型,移出时恢复
在除了IE6的情况下,可以通过CSS的:hover伪类来实现: 假如你想设定的固定区域为:<div id="test"></div>,那么只需要在CSS样式 ...
- 剑指offer-第七章面试案例2(树中两个节点的公共祖先节点)
import java.util.LinkedList; import java.util.Queue; import java.util.Stack; //树中两个节点的最低公共祖先 //第一种情况 ...
- 关于fpga的m9k的部分理解
1.控制信号包括时钟使能,读写使能,字节使能,地址使能,异步清零等 2.可配置为单端口,简单双端口,真双端口,fifo,rom,移位寄存器. 3.关于移位寄存器模式的介绍如下: 一个 ( w × m ...
- elasticsearch 动态模板
在elasticsearch中,如果你有一类相似的数据字段,想要统一设置其映射,就可以用到一项功能:动态模板映射(dynamic_templates). 每个模板都有一个名字用于描述这个模板的用途,一 ...
- yarn 管理nextjs 项目
预备环境 nodejs npm 1. yarn 安装 npm install -g yarn 2. nextjs 项目初始化 yarn add next react react-dom 3. 配置n ...
- laravel中session的过期时间
在项目开发的过程中,前后端分离 需要用session保存用户的登陆信息 这就涉及到session的有效期了 session又分为php中的session有效期和laravel中的session的有效期 ...
- paste:linux合并两个文件中的列(左右合并)
[root@www ~]# paste [-d] file1 file2 选项与参数: -d :后面可以接分隔字符.默认是以 [tab] 来分隔的! - :如果 file 部分写成 - ,表示来 ...
- PyYAML和configparser模块讲解
Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation ymal主要用于配置文件. Co ...
- mybatis foreach标签的解释 与常用之处
情景:查询数据库中文章的相关文章 文章为一个表 字段tags为相关文章字符串中间用','逗号进行啦分割 查询完一个文章后可以把tags字段构造为一个List<String> 然后利用这 ...
- python开发IO模型:阻塞&非阻塞&异步IO&多路复用&selectors
一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...