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;
    }
    
  • 相关阅读:
    【负载均衡】1.负载均衡介绍
    1.tcpdump、wireshark常用用法
    10.prometheus PromQL
    9.prometheus pushgateway介绍与部署
    服装行业生产按客户订制的解决方案
    课程总结
    第十四周课程总结&实验报告
    第十三周学习总结
    第十二周总结
    时间过得好快,第十一周就要截止了。不该遗憾的,要开心,要努力。
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135965.html
Copyright © 2011-2022 走看看