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

  题解:   很早之前就想做的树dp

正着情况太多 我们考虑反着过来考虑 $ dp[x] $表示x的子树和x本身使x不导通的概率

然后类似于容斥 从上到下维护每个点被接通的概率即可

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=5e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}


double dp[MAXN],up[MAXN];
int a[MAXN];

void dfs(int x,int pre){
    dp[x]=1.0*(100-a[x])/100;
    link(x){
	if(j->t==pre)continue;
	dfs(j->t,x);
	dp[x]*=(dp[j->t]+1.0*(1-dp[j->t])*(100-j->v)/100);
    }
}

double b[MAXN];
double st[MAXN],St[MAXN];
double ans[MAXN];
int tot;

void _dfs(int x,int pre){
    tot=0;
    link(x){
	if(j->t==pre)continue;
	b[++tot]=dp[j->t]+(1-dp[j->t])*(100-j->v)/100;
    }
    st[0]=St[tot+1]=1.0;
    inc(i,1,tot)st[i]=st[i-1]*b[i];
    dec(i,tot,1)St[i]=St[i+1]*b[i];
    int cnt=0;
    link(x){
	if(j->t==pre)continue;
	cnt++;
	up[j->t]=up[x]*st[cnt-1]*St[cnt+1];
	double t=up[j->t]+1.0*(1.0000-up[j->t])*(100-j->v)/100;
	up[j->t]=t;
	ans[j->t]=1.0-up[j->t]*dp[j->t];
	up[j->t]*=1.0*(100-a[j->t])/100;
    }
    link(x){
	if(j->t==pre)continue;
	_dfs(j->t,x);
    }
}

int main(){
    int n=read();
    int x,y,z;
    inc(i,2,n)x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
    inc(i,1,n)a[i]=read();
    up[1]=1.0*(100-a[1])/100;
    dfs(1,0);_dfs(1,0);
    ans[1]=1.00000-dp[1];
    double ans1=0;
    inc(i,1,n)ans1+=ans[i];
    printf("%.6f\n",ans1);
}

  

3566: [SHOI2014]概率充电器

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 1981  Solved: 921
[Submit][Status][Discuss]

Description

著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:
“采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧!

SHOI 概率充电器由 n-1 条导线连通了 n 个充电元件。进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定。
随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行间接充电。
作为 SHOI 公司的忠实客户,你无法抑制自己购买 SHOI 产品的冲动。在排了一个星期的长队之后终于入手了最新型号的 SHOI 概率充电器。
你迫不及待地将 SHOI 概率充电器插入电源——这时你突然想知道,进入充电状态的元件个数的期望是多少呢?

 

Input

第一行一个整数:n。概率充电器的充电元件个数。充电元件由 1-n 编号。
之后的 n-1 行每行三个整数 a, b, p,描述了一根导线连接了编号为 a 和 b 的
充电元件,通电概率为 p%。
第 n+2 行 n 个整数:qi。表示 i 号元件直接充电的概率为 qi%。

Output

输出一行一个实数,为进入充电状态的元件个数的期望,四舍五入到六位小数

Sample Input

3
1 2 50
1 3 50
50 0 0

Sample Output

1.000000

HINT

 

对于 100%的数据,n≤500000,0≤p,qi≤100。

posted @ 2019-03-04 17:27  wang9897  阅读(211)  评论(0编辑  收藏  举报