zoukankan      html  css  js  c++  java
  • [bzoj3566][SHOI2014]概率充电器【树形dp】

    【题目链接】
      https://www.lydsy.com/JudgeOnline/problem.php?id=3566
    【题解】
      套路题O(n)求出一个的解,然后O(1)换根。
      *注意除0的问题。

    /* --------------
        user Vanisher
        problem bzoj-3566
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    N       500010
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    struct node{
        int data,next;
        long double vote; 
    }e[N*2];
    int place,head[N],n,st[N*5],id,cnt[N];
    void build(int u, int v,long double w){
        e[++place].data=v; e[place].next=head[u]; head[u]=place; e[place].vote=w;
        e[++place].data=u; e[place].next=head[v]; head[v]=place; e[place].vote=w; 
    }
    long double p[N],ans[N],now[N],rd[N*5];
    long double solve(int x, int fa){
        now[x]=0;
        for (int ed=head[x]; ed!=0; ed=e[ed].next)
            if (e[ed].data!=fa){
                double nex=(p[e[ed].data]+(1-p[e[ed].data])*solve(e[ed].data,x))*e[ed].vote;
                if (cnt[e[ed].data]!=0) nex=e[ed].vote; 
                if (nex==1) cnt[x]++;
                    else now[x]=now[x]+(1-now[x])*nex;
            }
        return now[x];
    }
    void dfs(int x, int fa){
        st[++id]=x;
        for (int ed=head[x]; ed!=0; ed=e[ed].next)
            if (e[ed].data!=fa){
                rd[id]=e[ed].vote;
                dfs(e[ed].data,x);
                st[++id]=x;
                rd[id-1]=e[ed].vote;
            }
    }
    int main(){
        n=read();
        for (int i=1; i<n; i++){
            int u=read(), v=read();
            long double w=read()/100.0;
            build(u,v,w);
        }
        for (int i=1; i<=n; i++)
            p[i]=read()/100.0;
        solve(1,0);
        dfs(1,0);
        for (int i=1; i<=id; i++){
            if (cnt[st[i]]>0)
                ans[st[i]]=0;
                else ans[st[i]]=1-(p[st[i]]+(1-p[st[i]])*now[st[i]]);
            if (i<id){
                int x=st[i], y=st[i+1];
                double tmp=(p[y]+(1-p[y])*now[y])*rd[i];
                if (tmp==1||(cnt[y]>0&&rd[i]==1)) cnt[x]--;
                    else now[x]=(now[x]-tmp)/(1-tmp);
                tmp=(p[x]+(1-p[x])*now[x])*rd[i];
                if (tmp==1||(cnt[x]>0&&rd[i]==1)) cnt[y]++;
                    else now[y]=now[y]+(1-now[y])*tmp;
            }
        }
        long double maxans=0;
        for (int i=1; i<=n; i++)
            maxans=maxans+ans[i];
        printf("%.6Lf
    ",n-maxans);
        return 0;
    }
    
  • 相关阅读:
    GitLab 内存使用优化
    记一次 GitLab 的迁移过程
    MAC 最全快捷键
    IDEA中通过Java调用Python脚本报错
    远程服务调用PRC发展史
    分布式&微服务传送门
    (11)MySQL进阶篇SQL优化(InnoDB锁问题排查与解决)
    不懂物理的前端不是好的游戏开发者(一)—— 物理引擎基础
    京东购物小程序 | Taro3 项目分包实践
    浅谈树模型与集成学习-从决策树到GBDT
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135965.html
Copyright © 2011-2022 走看看