【SHTSC2014】概率充电器
题目自己搜,某dn再次“高度相似”,吃枣药丸 。
#include<bits/stdc++.h>
using namespace std;
int n,i,j,tot,head[1111111];
double ans,zj[1111111],f[1111111],s[1111111],fa[1111111],cs;
struct cyber{
int to,ne;
double wi;
}e[1111111];
void add(int x,int y,double z)
{
e[tot].wi=z;
e[tot].to=y;
e[tot].ne=head[x];
head[x]=tot++;
}
void dfs(int son,int father)
{
s[son]=(1-zj[son]);
for(int i=head[son];i!=-1;i=e[i].ne)
{
if(e[i].to!=father)
{
dfs(e[i].to,son);
fa[e[i].to]=son;
s[son]*=(s[e[i].to]+(1-s[e[i].to])*(1-e[i].wi));
}
}
}
void dfss(int st)
{
if(st==1) f[st]=1;
for(int i=head[st];i!=-1;i=e[i].ne)
{
if(e[i].to!=fa[st])
{
cs=(s[st]*f[st])*1.0;
cs=cs/((s[e[i].to]+(1-s[e[i].to])*(1-e[i].wi)));
f[e[i].to]=(cs+(1-cs)*(1-e[i].wi));
dfss(e[i].to);
}
}
}
int main()
{
freopen("charger.in","r",stdin);
freopen("charger.out","w",stdout);
memset(e,-1,sizeof e);
memset(head,-1,sizeof head);
scanf("%d",&n);
for(i=1;i<n;i++)
{
int x,y;
double z;
scanf("%d%d%lf",&x,&y,&z);
z/=100.0;
add(x,y,z);
add(y,x,z);
}
for(i=1;i<=n;i++)
{
scanf("%lf",&zj[i]);
zj[i]/=100.0;
}
dfs(1,0);
dfss(1);
for(i=1;i<=n;i++)
{
ans+=(1-(f[i]*s[i]));
}
printf("%.6f\n",ans);
}
还需要手动加栈。。。(改题中
算了,还是打BFS吧。。。