SHOI2014 charger probability (the DP tree) (the probability of the DP) (inclusion and exclusion)

Portal

Good question ah! It is clear from the sub-tree count again, then count again from his father

make f ( in ) f(u) represents a direct charge on electricity or charge on electricity from sub-tree of probabilities
the probability of the merger requires the inclusion-exclusion what P ( A B ) = P ( A ) + P ( B ) P ( A ) P ( B ) P(A|B)=P(A)+P(B)-P(A)*P(B)

followed by f ( in ) f(u) extension to be passed from father to
obviously if it came from his father not to embark on their own to go down

That probability is the probability of considering only the father and the father's other son
P ( A ) = P ( A B ) P ( B ) 1 P ( B ) P(A)=\frac{P(A|B)-P(B)}{1-P(B)} It is the father from the son's father and other electrical charge on the probability of

Then go down from father merger still inclusion and exclusion merger

Combined effects of tree d p dp routine and probability d p dp content transfer repellent

#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 5e5 + 5;
int read(){
	int cnt = 0, f = 1; char ch = 0;
	while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1; }
	while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
	return cnt * f;
}
int first[N], nxt[N << 1], to[N << 1], tot; double w[N << 1];
int n; double a[N], f[N];
void add(int x, int y, double z){nxt[++tot] = first[x], first[x] = tot, to[tot] = y, w[tot] = z; }
void dfs1(int u, int fa){
	f[u] = a[u];
	for(int i = first[u]; i; i = nxt[i]){
		int t = to[i]; if(t == fa) continue;
		dfs1(t, u); double p = w[i] * f[t];
		f[u] = f[u] + p - f[u] * p;
	}
}
void dfs2(int u, int fa){
	for(int i = first[u]; i; i = nxt[i]){
		int t = to[i]; if(t == fa) continue;
		double pa = f[t] * w[i];
		if(pa < 1){
			double pc = (f[u] - pa) / (1 - pa);
			double p = pc * w[i];
			f[t] = f[t] + p - p * f[t];
		} dfs2(t, u);
	}
}
int main(){
	n = read();
	for(int i = 1; i < n; i++){
		int x = read(), y = read(); double z = read(); z = z/100.0;
		add(x, y, z); add(y, x, z);
	} 
	for(int i = 1; i <= n; i++) a[i] = 1.0 * read() / 100.0;
	dfs1(1, 0); dfs2(1, 0); double ans = 0;
	for(int i = 1; i <= n; i++) ans += f[i];
	printf("%.6lf", ans); return 0;
}
Published 610 original articles · won praise 94 · views 50000 +

Guess you like

Origin blog.csdn.net/sslz_fsy/article/details/103497630