这个题看了kuangbin的题解
树上的概率dp,对待定系数法的解题思路又加深了一步认识。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
const int maxn=11000;
double A[maxn], B[maxn], C[maxn], K[maxn], E[maxn];
int fa[maxn], n;
vector<int> G[maxn];
void init_input()
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
G[i].clear();
for(int i=0; i<n-1; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for(int i=1; i<=n; i++)
{
double k, e;
scanf("%lf%lf", &k, &e);
K[i]=k/100.0;
E[i]=e/100.0;
}
}
void build(int u, int f)
{
fa[u]=f;
for(int i=0; i<G[u].size(); i++)
if(G[u][i]!=f)
build(G[u][i], u);
}
void dp(int u, int fa)
{
A[u]=K[u];
double p=B[u]=(1-K[u]-E[u])/G[u].size();
C[u]=1-K[u]-E[u];
double sum=0;
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i];
if(v==fa)continue ;
dp(v, u);
A[u]+=A[v]*p;
C[u]+=C[v]*p;
sum+=B[v]*p;
}
A[u]/=(1-sum);
B[u]/=(1-sum);
C[u]/=(1-sum);
}
int main()
{
int T, kase=0;
scanf("%d", &T);
while(T--)
{
init_input();
build(1, -1);
dp(1, -1);
printf("Case %d: ", ++kase);
if(fabs(1-A[1])<1e-9)
puts("impossible");
else
printf("%lf\n", C[1]/(1-A[1]));
}
return 0;
}