題目:
題意:給定樹形結構的n個元件,每個元件有一定概率自己充電,還有一定概率通過某條邊給其他元件充電,求充電的元件期望個數。n≤
500000
。題解:
樹形結構肯定能想到樹形dp,全樹對某點產生的貢獻一般可以通過一到兩遍樹形dp計算得出,本題所求期望等於每個元件被充電的概率之和。
設f[i]
表示i
被充電的概率,g[i]
表示i
被以i
為根的子樹充電的概率。
關於g
,g[i]
應該為自己充電的概率和兒子們對其充電的概率的並集,這可由一遍dfs計算得出,概率的並集則可利用公式:p(a + b) = p(a) + p(b) - p(a) * p(b)
。
關於f
,g[i]
已經計算出i被孩子充電的概率,現在只需要計算出i
被父親充電的概率求並即可,這等價於父親不被i
充電反給i
充電的概率。考慮一條邊e
的父親是u
,兒子是v
,兒子被父親充電的概率應該是f[u]
中除去被v
充電的概率後的值,仍可以利用上面的公式拆出:p(a) = [p(a + b) - p(b)] / [1 - p(b)]
。計算f
,除了根沒有父親外,其他點可以再做一遍dfs得出。
兩遍樹形dp即可,時間複雜度o(
n)。**:
#include
#include
#include
using
namespace
std;
typedef pair edge;
const
int maxn = 500001;
const
double eps = 1e-8;
int n;
vector
e[maxn];
double q[maxn], f[maxn], g[maxn], ans;
inline
bool cmp0(double x)
inline
double merge(double x, double y)
inline
double split(double r, double y)
void dfs1(int u, int fa)
}void dfs2(int u, int fa)
}int main()
for(int i = 1; i <= n; ++i)
dfs1(1, 0);
f[1] = g[1];
dfs2(1, 0);
printf("%.6f\n", ans);
return
0;}
bzoj3566 SHOI2014 概率充電器
n個充電器連成一棵樹。第i個充電器有p i 的概率直接充電。每條導線有一定機率可以導電。可以導電的導線形成的聯通塊中只要存在直接充電的結點整個聯通塊的充電器均進入充電狀態。問期望進入充電狀態的充電器個數 顯然可知我們只需要得到f i 表示i進入充電狀態的概率 那麼a ns f i 我們把無根樹變有根...
bzoj3566 SHOI2014 概率充電器
著名的電子產品品牌 shoi 剛剛發布了引領世界潮流的下一代電子產品 概率充電器 採用全新奈米級加工技術,實現元件與導線能否通電完全由真隨機數決定 shoi 概率充電器,您生活不可或缺的必需品 能充上電嗎?現在就試試看吧 shoi 概率充電器由 n 1 條導線連通了 n 個充電元件。進行充電時,每條...
BZOJ3566 SHOI2014 概率充電器
bzoj luogu 很顯然的兩遍樹dp吧。設 f i 表示只考慮 i 的子樹,i 點沒有電的概率。f i q i prod f v 1 f v 1 p e 為了方便表示把後面那一坨記為 h v 即 h i f i 1 f i 1 p e 然後再記乙個 g i 表示 i 的父親不向 i 供電的概率,...