• [SHOI2014]概率充电器


    · 题解

      首先考虑设ƒi为i发光的概率,那么它可以从子节点、自身、和父节点传过来,但是,这是其中至少有一个通电的问题,也就是“或”,因为它们的目的是一样的——都是使当前通电,也就是说它们并不是互斥的状态,比如子节点和父节点都是50%,那么这个节点的通电概率就是$100%$了吗?显然不是,虽然有这个公式:

                    

      难写,所以不接受。但是,假如我们只看无法通电的概率呢?这样就满足乘法原理了。

      有了这个,简单树形DP换根即可。

    · 代码

      

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 
      7 const int MAXN = 5e05 + 10;
      8 
      9 struct LinkedForwardStar {
     10     int to;
     11     double w;
     12     
     13     int next;
     14 } ;
     15 
     16 LinkedForwardStar Link[MAXN << 1];
     17 int Head[MAXN]= {0};
     18 int size = 0;
     19 
     20 void Insert (int u, int v, double w) {
     21     Link[++ size].to = v;
     22     Link[size].w = w;
     23     Link[size].next = Head[u];
     24     
     25     Head[u] = size;
     26 }
     27 
     28 const int Root = 1;
     29 
     30 int N;
     31 
     32 double Dire[MAXN];
     33 
     34 double f[MAXN];
     35 
     36 void DFS1 (int root, int father) {
     37     f[root] = 1 - Dire[root];
     38     
     39     for (int i = Head[root]; i; i = Link[i].next) {
     40         int v = Link[i].to;
     41         double w = Link[i].w;
     42         
     43         if (v == father)
     44             continue;
     45         
     46         DFS1 (v, root);
     47         
     48         f[root] *= f[v] + (1 - f[v]) * (1 - w);
     49     }
     50 }
     51 
     52 double g[MAXN];
     53 
     54 void DFS2 (int root, int father, double fval) {
     55     double fp = g[father] * (f[father] / (f[root] + (1 - f[root]) * (1 - fval)));
     56     g[root] = fp + (1 - fp) * (1 - fval);
     57     
     58     for (int i = Head[root]; i; i = Link[i].next) {
     59         int v = Link[i].to;
     60         double w = Link[i].w;
     61         
     62         if (v == father)
     63             continue;
     64         
     65         DFS2 (v, root, w);
     66     }
     67 }
     68 
     69 int main () {
     70     scanf ("%d", & N);
     71     
     72     for (int i = 1; i < N; i ++) {
     73         int u, v, w;
     74         scanf ("%d%d%d", & u, & v, & w);
     75         
     76         double neww = (double) w / 100.0;
     77         Insert (u, v, neww), Insert (v, u, neww);
     78     }
     79     
     80     for (int i = 1; i <= N; i ++) {
     81         int w;
     82         scanf ("%d", & w);
     83         
     84         Dire[i] = (double) w / 100.0;
     85     }
     86     
     87     DFS1 (Root, 0);
     88     g[1] = 1.0;
     89     DFS2 (Root, 0, 0);
     90     
     91     double ans = 0.0;
     92     for (int i = 1; i <= N; i ++)
     93         ans += (1 - f[i] * g[i]);
     94     
     95     printf ("%.6f
    ", ans);
     96     
     97     return 0;
     98 }
     99 
    100 /*
    101 3
    102 1 2 50
    103 1 3 50
    104 50 0 0
    105 */
    106 
    107 /*
    108 5
    109 1 2 90
    110 1 3 80
    111 1 4 70
    112 1 5 60
    113 100 10 20 30 40
    114 */
    View Code
  • 相关阅读:
    Cesium中的坐标系及转换
    Cesium Workshop
    window.postMessage 跨窗口,跨iframe javascript 通信
    VUE课程参考---7、跑马灯效果
    VUE课程---9、事件绑定v-on
    VUE课程---8、属性绑定v-bind
    VUE课程---7、解决插值表达式闪烁问题
    小谈chrome调试命令:console.log的使用
    Hadoop平台配置总结
    hadoop 关闭进程时报错no 进程 to stop
  • 原文地址:https://www.cnblogs.com/Colythme/p/9717731.html
Copyright © 2020-2023  润新知