zoukankan      html  css  js  c++  java
  • [SHOI2014] 概率充电器

    首先记 (f_u) 表示 (u) 不被以 (u) 为根的子树内点通上电的概率。

    不难列出这样一个式子:

    (f_u=displaystyle(1-p_u)*prod_{v in subtree u}f_v*e(u,v))

    其中 (p_u) 表示直接充 (u) 的概率。

    但是这个式子有个 bug,它处理不了给 (u) 导电的点在 (u) 子树外的情况。

    那么我们采取换根的思想,记 (g_u) 表示 (u) 不通电的概率,则 (g_u) 可以通过 (u) 的子树和剩余部分计算,子树部分我们已经处理过,而剩余部分可以通过 (u) 的父亲计算,记 (h_u) 表示非 (u) 子树里的点导电给 (u) 的概率。

    那么 (h_u = dfrac{g_{fa}}{1-e(fa,u)+e(fa,u)*f_u})

    那么 (g_u = f_u*(1-e(fa,u)+e(fa,u)*f_u))

    那么答案就是 (displaystyle sum_{i=1}^{n}(1-g_i))

    #include <bits/stdc++.h>
    #define reg register
    #define ll long long
    using namespace std;
    const int MAXN = 5e5 + 10;
    int n, E, head[MAXN], nxt[MAXN << 1], pnt[MAXN << 1];
    double val[MAXN << 1], p[MAXN], f[MAXN], g[MAXN], h[MAXN];
    inline void clear() {
      E = 0, memset(head, -1, sizeof(head));
    }
    inline void addedge(int x, int y, double v) {
      nxt[E] = head[x], pnt[E] = y, val[E] = v, head[x] = E++;
    }
    inline void dfs1(int u, int fa) {
      f[u] = 1 - p[u];
      for(reg int i = head[u]; i != -1; i = nxt[i]) {
        int v = pnt[i];
        if(v == fa) continue;
        dfs1(v, u), f[u] *= (1 - val[i] + val[i] * f[v]);
      }
    }
    inline void dfs2(int u, int fa, int id) {
      if(u == 1) g[u] = f[u];
      else h[u] = g[fa] / (1 - val[id] + val[id] * f[u]), g[u] = f[u] * (1 - val[id] + val[id] * h[u]);
      for(reg int i = head[u]; i != -1; i = nxt[i]) {
        int v = pnt[i];
        if(v == fa) continue;
        dfs2(v, u, i);
      }
    }
    inline void work() {
      scanf("%d", &n), clear();
      for(reg int i = 1; i < n; ++i) {
        int u, v;
        double d;
        scanf("%d%d%lf", &u, &v, &d), d *= 0.01, addedge(u, v, d), addedge(v, u, d);
      }
      for(reg int i = 1; i <= n; ++i) scanf("%lf", &p[i]), p[i] *= 0.01;
      dfs1(1, 0), dfs2(1, 0, 0);
      double ans = 0;
      for(reg int i = 1; i <= n; ++i) ans += 1.0 - g[i];
      printf("%.6f
    ", ans);
    }
    int main() {
      int _ = 1;
      // scanf("%d", &_);
      while(_--) work();
      return 0;
    }
    
    
  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/Lonely-233/p/13659045.html
Copyright © 2011-2022 走看看