[bzoj 3566][SHOI 2014]概率充电器

传送门

Description

SHOI 概率充电器由 n-1 条导线连通了 n 个充电元件。进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定。

随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行间接充电。

进入充电状态的元件个数的期望是多少呢?

Solution

\[
E=\sum f_i\ \ \ 其中f_i表示节点i通电的概率
\]

那么怎么求\(f_i\)呢?显然,一个点通电有三种情况:来自i的父亲节点、来自i的某个儿子节点、来自i自己

首先,要了解的是:
\[
P(A\cup B)=P(A)+P(B)-P(A \cap B)=P(A)+P(B)-P(A)*P(B)
\]

  • 只考虑自己给自己充电的情况:\(f_i=q_i\),也就是它直接通电的可能性
  • 只考虑自己给自己充电和儿子给自己充电两种情况:考虑\(dfs\),回溯的时候用儿子\(v\)更新父亲\(u\),儿子给父亲充电的概率是\(从儿子充电p_{从儿子充电}=p(u,v)*f_v\),然后\(从儿子充电从儿子充电f_u=f_u+p_{从儿子充电}-f_u*p_{从儿子充电}\)
  • 考虑三种情况,\(dfs\)的时候从上到下用父亲节点\(u\)更新儿子节点\(v\),但是,我们要如何求出父亲给儿子充电的概率呢?显然是父亲得到电的概率*\(p(u,v)\),而这里父亲得到电的概率应该不包含从\(v\)得到电的情况。

不包含\(v\)的情况怎么算呢,考虑逆推回去。

因为:\(P(A\cup B)=P(A)+P(B)-P(A)*P(B)\)

所以:\(P(A)=\frac{P(A \cup B)}{1-P(B)}\)

有第二步可知,\(P(B)=p(u,v)*f_v\),\(P(A)=f_u\)

如果\(P(B)=1\)怎么办呢?这是后是算不出\(P(A)\)的,但是这个时候显然\(f_v=1\),那么他已经不需要再计算了

这样,\(从父亲充电p_{从父亲充电}=P(A)\)

? 所以就可以更新\(f_v\)辣,\(从父亲充电从父亲充电f_v=f_v+p_{从父亲充电}-f_v*p_{从父亲充电}\)

如何判断\(f_v=1\)?用\(abs(f_v-eps)<eps\)即可

Code?

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
#define MN 500005
#define eps (1e-8)
#define db double
#define abs(x) ((x)>0?(x):-(x))
struct edge{int to,p,nex;}e[MN<<1];
int en,hr[MN];
inline void ins(int f,int t,int p)
{
    e[++en]=(edge){t,p,hr[f]};hr[f]=en;
    e[++en]=(edge){f,p,hr[t]};hr[t]=en;
}
double f[MN],ans;
int n,a,b;
void dfs1(int x=1,int fa=0)
{
    register int i;
    for(i=hr[x];i;i=e[i].nex)if(fa^e[i].to)
        dfs1(e[i].to,x),f[x]=f[x]+f[e[i].to]*((db)e[i].p/100.)-f[e[i].to]*f[x]*((db)e[i].p/100.);
}
void dfs2(int x=1,int fa=0)
{
    register int i;
    for(i=hr[x];i;i=e[i].nex)if(fa^e[i].to)
    {
        if(abs(1.-f[e[i].to])>eps)
        {
            double down=(f[x]-f[e[i].to]*((db)e[i].p/100.))/(1-f[e[i].to]*((db)e[i].p/100.))*((db)e[i].p/100.);
            f[e[i].to]=f[e[i].to]+down-f[e[i].to]*down;
        }
        dfs2(e[i].to,x);
    }
}
int main()
{
    n=read();
    register int i,x,y;
    for(i=1;i<n;++i) x=read(),y=read(),ins(x,y,read());
    for(i=1;i<=n;++i) f[i]=read()/100.;
    dfs1();dfs2();
    for(i=1;i<=n;++i) ans+=f[i];
    printf("%.6lf",ans);
    return 0;
}


Blog来自PaperCloud,未经允许,请勿转载,TKS!

原文地址:https://www.cnblogs.com/PaperCloud/p/10219009.html

时间: 2024-11-10 14:03:42

[bzoj 3566][SHOI 2014]概率充电器的相关文章

BZOJ 3566 SHOI 2014 概率充电器 概率DP

题目大意:给出一棵树,每个节点都有一个充电概率,每一条边有一个导电概率,求期望有多少个点充电. 思路:写不出题解,粘一个详细的地址:http://wyfcyx.is-programmer.com/posts/74623.html CODE: #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #i

解题:SHOI 2014 概率充电器

题面 显然就是在求概率,因为期望乘的全是1....然后就推推推啊 设$fgg[i]$表示这个点父亲没给他充上电的概率,$sgg[i]$表示这个点子树(和它自己没给他充上电的概率),然后这个点没充上电的概率就是$fgg[i]*sgg[i]$ 我们发现我们在树上转移的话$fgg$反过来依赖儿子,也就是依赖于$sgg$,那我们先把$sgg$求出来 $sgg[i]=$ 1 #include<cstdio> 2 #include<cstring> 3 #include<algorith

BZOJ 3564 SHOI 2014 信号增幅仪 坐标变换+最小圆覆盖

题目大意:给出平面上的一些点,现在让你用一个长轴与x轴成一定角度的,长轴:短轴已知的椭圆来覆盖所有的坐标,求最小的短轴长度. 思路:很明显,这个椭圆的形状和放置状态已经给出了,但是没有办法求最小拖圆覆盖啊.采用坐标变换,将椭圆变成圆.首先我们先让长轴与x轴平行,将平面上的所有点都旋转这个角度.之后只需要让所有点的x坐标除以长轴:短轴就可以了.剩下的就是最小圆覆盖了. 注:坐标旋转公式: x' = x * cos(a) - y * sin(a) y' = x * sin(a) + y * cos(

bzoj 3566: [SHOI2014]概率充电器 树形DP

首先普及一个概率公式 P(A+B)=P(A)+P(B)-P(AB) 题意:一些充电元件和导线构成一棵树,充电元件是否能充电有2种情况, 1.它自己有qi%的概率充电 2.与它相邻的元件通过导线给它充电(导线有p%的概率导通) 求最终充了电的元件的期望 题解:首先可以将元件能否充电分成3种情况考虑, 1.它自己给自己充好了电 2.它的儿子方向给它传送了电 3.它的父亲方向给它传送了电. 对于1,题目已经给出可以直接赋值, 对于2,可以通过一次树的深度遍历求得.pson[now]=pson[now]

bzoj 3566: [SHOI2014]概率充电器

Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器:"采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧!"SHOI 概率充电器由 n-1 条导线连通了 n 个充电元件.进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定.随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行间接充电.作为 SHO

【BZOJ】3566: [SHOI2014]概率充电器

[算法]树型DP+期望DP [题意]一棵树上每个点均有直接充电概率qi%,每条边有导电概率pi%,问期望有多少结点处于充电状态? [题解]引用自:[BZOJ3566][SHOI2014]概率充电器 树形DP 概率DP by 空灰冰魂 最大的难点在于计算每个点充电期望时,两个节点各自的期望都会影响对方的期望. 所以考虑转化对象,改为求每个节点充不上电的期望,充不上电就不用考虑两者的相互影响. fi表示结点i由子结点和自身充不上电的概率 gi表示结点i由父结点充不上电的概率 第一次DFS: hi表示

●BZOJ 3566 [SHOI2014]概率充电器

题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3566题解: 概率dp,树形dp 如果求出每个点被通电的概率t, 那么期望答案就是t1×1+t2×1+t3*1+...+tn×1 现在问题就是要去求每个点被通电的概率. 因为是一颗树,所以每个点是否通电只由三个因素决定: 自己给自己通电;儿子给自己通电;父亲给自己通电. 这里采取求反面的方法: 对于每个点u, 1.求出u所在的子树不能给u点通电的概率f[u]. 2.求出u的父亲不能给u点通电

【BZOJ3566】概率充电器(动态规划)

[BZOJ3566]概率充电器(动态规划) 题面 BZOJ Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: "采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧! " SHOI 概率充电器由 n-1 条导线连通了 n 个充电元件.进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定. 随后电能可以从直

Bzoj3566 [SHOI2014]概率充电器

Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 999  Solved: 428 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧!”SHOI 概率充电器由 n-1 条导线连通了 n 个充电元件.进行充电时,每条导线是否可以导电以概率决定,每一个充电元