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( ...
随机推荐
- bzoj3262: 陌上花开(CDQ+树状数组处理三维偏序问题)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3262 题目大意:中文题目 具体思路:CDQ可以处理的问题,一共有三维空间,对于第一维我们 ...
- tarjan算法(求强连通子块,缩点)
tarjan算法求图中的强连通子图的个数. #include<iostream> #include<stack> #include<queue> #include& ...
- Git更新远程仓库代码到本地(转)
参考链接:https://blog.csdn.net/chailyuan/article/details/53292031 在下载一个较大的github项目以后,当该项目代码更新以后,我们想将更新的内 ...
- Setup Mission End
编写FPSGameMode 新建函数OnMissionComplete,并设置为蓝图可实现事件 UFUNCTION(BlueprintImplementableEvent,Category=" ...
- python第一天,简单输出及基本运算符
1.安装步骤网上很多详细的图文资料,这里就不一一赘述. 我的环境:win7 64bit +python-3.7.0b2 2.简单的输出(3.0之后和之前的版本略有不同) 1)打开控制台输入python ...
- workqueue --最清晰的讲解
带你入门: 1.INIT_WORK(struct work_struct *work, void (*function)(void *), void *data) 上面一句只是定义了work和work ...
- 基于React 的前端UI开发框架 及与Electron 的结合 https://cxjs.io/
1.cxjs 基于React 的前端UI开发框架 https://cxjs.io/ coreu http://coreui.io/ 2.antd-admin ...
- HAProxy详解(三):基于虚拟主机的HAProxy负载均衡系统配置实例【转】
一.基于虚拟主机的HAProxy负载均衡系统配置实例 1.通过HAProxy的ACL规则配置虚拟主机: 下面将通过HAProxy的ACL功能配置一套基于虚拟主机的负载均衡系统.这里操作系统环境为:Ce ...
- Python3学习笔记32-xlwt模块
xlwt模块是用来写入excel的第三方模块,需要下载安装后才能使用. 设置字体样式 import xlwt #初始化一个excel excel = xlwt.Workbook(encoding='u ...
- 微信小程序-输入框输入文字后,将光标移到文字中间,接着输入文字后光标又自动跳到最后
问题描述: input输入框输入一段文字后,将光标移到文字中间,接着输入文字后光标又自动跳到最后去了. 原因: input事件中,给input框绑定任何事件后,在处理事件时 setData之后就会让光 ...