bzoj 3566
非常好也是比较难的题
首先,不难看出这是一道树形的概率dp
那么我们就要考虑转移
我们发现,一个点能充上电的概率是这个点本身通电的概率+这个点的子节点给他传过来电的概率+这个点的父节点给他传过来电的概率
但是这里的加法都是概率的加法,也就是说满足如下公式:
那么如果是三元事件,这个公式会更为复杂,所以这一点并不是特别容易计算
那么我们考虑正难则反:
一个点没有电的概率=父节点没传过来电的概率*子树内部没传过来电的概率(这里的子树内部包括子节点和这个节点本身)
所以我们用两个状态分别计算这两个概率:
设状态f[i]表示以i为根节点的子树中没有给i传过来电的概率,g[i]表示i的父节点没有给i传过来电的概率
那么显然,f[i]更容易转移,所以我们先转移f[i]
一个点的子树内部都没给他传过来电的概率,根据乘法原理,有:
解释:对于每个子节点,有两种可能向上继承:一是本身这个节点没有电,二是这个节点有电了但是连接这两点之间的边没有电
而且显然要求根节点本身不能有电,所以再乘一个根节点没有电的概率
这样第一个dfs就完成了
至于g[i]的转移,也是同理,首先,最大的根节点没有父节点,所以g[root]=1(这里root设为1)
然后从上向下更新,一个父节点不能更新子节点的情况是父节点没有通电或父节点通电了但中间的边没有通电,算一下这两部分的概率即可。
但是有个问题:我们知道,父节点没有通电的概率有一部分是由于子节点没有通电引起的,但是这里是用父节点更新子节点,这样会产生重复计算
所以我们在计算父节点没有通电的概率时要除掉子节点向父节点产生的贡献,这样才准确
所以表达式如下:
这就是第二个dfs
最后计算答案即可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
struct Edge
{
int next;
int to;
double p;
}edge[1000005];
double ret[500005];
int head[500005];
double q[500005];
int cnt=1;
double f[500005];
double g[500005];
int n;
void init()
{
memset(head,-1,sizeof(head));
cnt=1;
}
void add(int l,int r,double pp)
{
edge[cnt].next=head[l];
edge[cnt].to=r;
edge[cnt].p=pp;
head[l]=cnt++;
}
void dfs(int x,int fx)
{
f[x]=(1-q[x]);
for(int i=head[x];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
if(to==fx)
{
continue;
}
dfs(to,x);
f[x]*=f[to]+(1.0-f[to])*(1.0-edge[i].p);
}
}
void redfs(int x,int fx)
{
for(int i=head[x];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
if(to==fx)
{
continue;
}
double p0=f[x]*g[x]/(double)(f[to]+(1-f[to])*(1-edge[i].p));//父节点不通电的概率
g[to]=p0+(1-p0)*(1-edge[i].p);
redfs(to,x);
}
}
int main()
{
scanf("%d",&n);
init();
for(int i=1;i<n;i++)
{
int x,y;
double z;
scanf("%d%d%lf",&x,&y,&z);
z*=0.01;
add(x,y,z);
add(y,x,z);
}
for(int i=1;i<=n;i++)
{
scanf("%lf",&q[i]);
q[i]*=0.01;
}
dfs(1,1);
g[1]=1.0;
redfs(1,1);
double ans=0;
for(int i=1;i<=n;i++)
{
ans+=1.0-f[i]*g[i];
}
printf("%.6lf\n",ans);
return 0;
}
bzoj 3566的更多相关文章
- 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]\)的概率导电,电可以沿边传递使其他点间接充电.求进入充电状态的点期望个数 糖教题解传 ...
- ●BZOJ 3566 [SHOI2014]概率充电器
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3566题解: 概率dp,树形dp 如果求出每个点被通电的概率t, 那么期望答案就是t1×1+t ...
- BZOJ.3566.[SHOI2014]概率充电器(概率DP 树形DP)
BZOJ 洛谷 这里写的不错,虽然基本还是自己看转移... 每个点的贡献都是\(1\),所以直接求每个点通电的概率\(F_i\),答案就是\(\sum F_i\). 把\(F_x\)分成:父节点通电给 ...
- 【BZOJ 3566】 3566: [SHOI2014]概率充电器 (概率树形DP)
3566: [SHOI2014]概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线能否通电 ...
- bzoj 3566 [SHOI2014]概率充电器——树型
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3566 一眼看上去高斯消元.n^3不行. 竟然直接去看了TJ.发现树型dp.一下想到了自己还没 ...
- bzoj 3566: [SHOI2014]概率充电器
Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器:"采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率 ...
- BZOJ 3566 [SHOI2014]概率充电器 ——期望DP
期望DP. 补集转化,考虑不能被点亮的情况, 然后就是三种情况,自己不能亮,父亲不能点亮它,儿子不能点亮它. 第一次计算比较容易,第二次计算的时候需要出去第一次的影响,因为一条线只能传导一次 #inc ...
- bzoj 3566: [SHOI2014]概率充电器【树形概率dp】
设g[u]为这个点被儿子和自己充上电的概率,f[u]为被儿子.父亲和自己充上电的概率 然后根据贝叶斯公式(好像是叫这个),1.P(A+B)=P(A)+P(B)-P(A)*P(B),2.P(A)=(P( ...
随机推荐
- Python pipenv
pipenv都包含什么? pipenv 是 Pipfile 主要倡导者.requests 作者 Kenneth Reitz 写的一个命令行工具,主要包含了Pipfile.pip.click.reque ...
- 批量清除react中的计时器小组件
在Timers的父组件被卸载时,批量清除各个计时器.
- JSP表达式语音EF--2
JSP 表达式语言 | 菜鸟教程 http://www.runoob.com/jsp/jsp-expression-language.html
- 黑马程序员_Java基础视频-深入浅出精华版--视频列表
\day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...
- scrapy基本使用(一)
scrapy基本使用(一) 参考文档:Scrapy入门教程 http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html scrapy ...
- python初级实战-----主机在线情况监控web
背景 公司有600多台服务器,打算写一个小程序,能一眼看见哪些服务器不在线. 大体思路是: 1.把所有服务器ip存进数据库,ping命令判断服务器是否在线 2.更新数据库中ip的状态 3.简单的web ...
- MySQL触发器trigger的使用
https://www.cnblogs.com/geaozhang/p/6819648.html 触发器的触发 语句的错误 和 触发器里面 错误 都不会运行 NEW与OLD详解 MySQL 中定义了 ...
- Ettercap内网渗透
最近网速很卡,于是想到有人在蹭网,怎么捉弄一下呢? 1.开启ettercap ettercap -G 2. Hosts->Scan,List 发现有几个新的地址192.168.1.71,192. ...
- python之async-timeout模块
async-timeout 兼容async的超时的上下文管理器 async-timeout的timeout和asyncio的wiat_for比较 首先从使用上来说asyncio.wait_for(aw ...
- npm 安装 sass-loader 失败的解决办法
You got to add python to your PATH variable. One thing you can do is Edit your Path variable now and ...