做法:其实题目中给的就是一棵有根树,一开始闹惨以为可能存在多个连通分量。
带环的,数据量又那么大,又看了大神的博客,慢慢神伤...
如果当前节点是叶子节点,
那么dp[x]=1-e[x]-k[x]+k[x]*dp[1]+sigma(p[i]*dp[fahter[i]]);
如果不是
dp[x]=1-e[x]-k[x]+k[x]*dp[1]+sigma(p[i]*father[i])+sigma(p[i]*son[i]);
由于叶子节点没有son,而且,某个节点中的,他的儿子的faher就是自己(废话了,,),那么,在由叶子向根的递推过程中
所以dp[x]=(a[x]*dp[father]+b[x]*dp[1]+c[x])/(1-sigma(son(a[x])));
做的时候#define居然能让我写错了,,,
#include<cstdio> #include<cstring> #include<cmath> #define no_no 1e50 #define zero(x) fabs(x)<1e-9 const int LMT=100003; struct line { int u,v; int next; }le[LMT<<1]; int next[LMT],all,du[LMT]; double x[LMT],y[LMT],z[LMT],e[LMT],k[LMT]; void init(void) { memset(next,-1,sizeof(next)); memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); memset(z,0,sizeof(z)); memset(du,0,sizeof(du)); all=0; } void insert(int u,int v) { le[all].u=u; le[all].v=v; le[all].next=next[u]; next[u]=all++; } bool dfs(int u,int pre) { int v,xx; double temy=0; z[u]+=1-e[u]-k[u]; x[u]+=k[u]; for(xx=next[u];xx!=-1;xx=le[xx].next) if(le[xx].v!=pre) { v=le[xx].v; if(!dfs(v,u)&&1-k[u]-e[u]>0)return 0; x[u]+=x[v]*(1-k[u]-e[u])/du[u]; temy+=y[v]*(1-k[u]-e[u])/du[u]; z[u]+=z[v]*(1-k[u]-e[u])/du[u]; } if(pre!=-1)y[u]+=(1-k[u]-e[u])/du[u]; if(zero((temy-1.0)))return 0; x[u]/=(1-temy); y[u]/=(1-temy); z[u]/=(1-temy); return 1; } int main(void) { int T,I,i,u,v,n; scanf("%d",&T); for(I=1;I<=T;I++) { init(); scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d",&u,&v); insert(u,v); insert(v,u); du[u]++;du[v]++; } for(i=1;i<=n;i++) { scanf("%lf%lf",&k[i],&e[i]); e[i]/=100; k[i]/=100; } printf("Case %d: ",I); if(!dfs(1,-1)||zero((1.0-x[1]))) printf("impossible"); else printf("%.6lf",z[1]/(1-x[1])); printf("\n"); } return 0; }