列表

详情


NC20589. [SHOI2014]概率充电器

描述

著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧! ” SHOI 概率充电器由 n-1 条导线连通了 n 个充电元件。进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定。 随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行间接充电。 作为 SHOI 公司的忠实客户,你无法抑制自己购买 SHOI 产品的冲动。在排了一个星期的长队之后终于入手了最新型号的 SHOI 概率充电器。 你迫不及待地将 SHOI 概率充电器插入电源——这时你突然想知道,进入充电状态的元件个数的期望是多少呢?

输入描述

第一行一个整数:n。概率充电器的充电元件个数。充电元件由 1-n 编号。 
之后的 n-1 行每行三个整数 a, b, p,描述了一根导线连接了编号为 a 和 b 的 充电元件,通电概率为 p%。 
第 n+2 行 n 个整数:qi。表示 i 号元件直接充电的概率为 qi%。

输出描述

输出一行一个实数,为进入充电状态的元件个数的期望,四舍五入到六位小数

示例1

输入:

3 
1 2 50 
1 3 50 
50 0 0

输出:

1.000000

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 658ms, 内存消耗: 65216K, 提交时间: 2020-03-27 18:23:01

#include<bits/stdc++.h>
using namespace std;

const int N=1e6+100;
vector<pair<int,int> >G[N];

double  dp[N],p[N];
int n;
void dfs1(int x,int fa)
{
	dp[x]=1-p[x];//表示当前节点不来电的概率 
	for(auto S:G[x])
	{
		int v=S.first,w=S.second;
		if(v==fa) continue;
		dfs1(v,x);
		dp[x]*=1-(1-dp[v])*(1.0*w/100);
	}
}

void dfs2(int x,int fa)//换根 
{
	for(auto S:G[x])
	{
		int v=S.first,w=S.second;
		if(v==fa) continue;
		double tmp=1-(1-dp[v])*(1.0*w/100);
		if(tmp>1e-8) dp[v]=dp[v]*(1-(1-dp[x]/tmp)*(1.0*w/100));
		dfs2(v,x);
	}
}
int main()
{
    ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int x,y,w;
		cin>>x>>y>>w;
		G[x].push_back(make_pair(y,w));
		G[y].push_back(make_pair(x,w));
	}
	for(int i=1;i<=n;i++) cin>>p[i],p[i]=1.0*p[i]/100;
	dfs1(1,0);
	dfs2(1,0);
	double ans=0;
	for(int i=1;i<=n;i++) ans+=(1-dp[i]);
	printf("%.6f\n",ans);
	
	return 0;
} 

上一题