bzoj 3566: [SHOI2014] probability charger mathematical expectation change root dp +

code: 

#include <bits/stdc++.h>    
#define N 500002         
#define LL long long 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;   
int n,edges;    
double f[N],g[N],perc[N<<1],q[N]; 
int hd[N],to[N<<1],nex[N<<1]; 
void add(int u,int v,double c) 
{
	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,perc[edges]=c; 
} 
void dfs1(int u,int ff)          
{
	f[u]=1-q[u];           
	for(int i=hd[u];i;i=nex[i])        
	{  
		int v=to[i]; 
		if(v==ff)    continue;                              
		dfs1(v,u); 
		f[u]*=(1-perc[i]+perc[i]*f[v]);             
	}
} 
void dfs2(int u,int ff,int j) 
{  
	if(u==1)   g[u]=f[u];  
	else 
	{
		double p=g[ff]/(1-perc[j]+perc[j]*f[u]);            
		g[u]=f[u]*(1-perc[j]+perc[j]*p);      
	} 
	for(int i=hd[u];i;i=nex[i]) 
	{
		int v=to[i]; 
		if(v==ff) continue;   
		dfs2(v,u,i);   
	}
}
int main() 
{ 
	// setIO("input");  
	int i,j; 
	scanf("%d",&n);            
	for(i=1;i<n;++i) 
	{
		int x,y,z; 
		scanf("%d%d%d",&x,&y,&z),add(x,y,(double)z/100),add(y,x,(double)z/100);    
	}    
	for(i=1;i<=n;++i)    scanf("%lf",&q[i]),  q[i]/=100;     
	dfs1(1,0); 
	dfs2(1,0,0);    
	double ans=0;   
	for(i=1;i<=n;++i)  ans+=1.0-g[i]; 
	printf("%.6lf",ans);               
	return 0; 
}   

  

Guess you like

Origin www.cnblogs.com/guangheli/p/11794238.html