zoukankan      html  css  js  c++  java
  • [bzoj2878][Noi2012]迷失游乐园(基环树dp)

    [bzoj2878][Noi2012]迷失游乐园(基环树dp)

    bzoj luogu

    题意:一颗数或是基环树,随机从某个点开始一直走,不走已经到过的点,求无路可走时的路径长期望。

    对于一棵树:

    用两个$dp$数组分别记录从这个点起向上向下走的期望

    向下走的$dp$不用多说

    向上走的$dp$:

    对于从$u$计算$v$的dp

    $dp[v]$应当是从u向周围引出所有路径减去走向t的路径的期望后再除以$deg_{u}-1$

    对于基环树:

    环上的点很少。

    此时环上的点的向上$dp$指从u出发向环上两头走的期望。

    如何计算:对于环上每一个点都向环的两头各dp一次取平均值。

    完毕。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=100011;
    const double eps=1e-8;
    template<typename TP>void read(TP &kk){
        #define ak *
        TP phy=0,ioi=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')ioi=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){phy=phy*10+ch-'0';ch=getchar();}
        kk=phy ak ioi;
    }
    int n,m;
    struct sumireko
    {
        int to,ne,w;
    }e[N*2];
    int he[N],ecnt;
    void addline(int f,int t,int w)
    {
        e[++ecnt].to=t;
        e[ecnt].ne=he[f];
        he[f]=ecnt;
        e[ecnt].w=w;
    }
    bool onr[N];
    double deg[N],sc[N],dpu[N],dpd[N];
    void dfs1(int x,int f)
    {
        for(int i=he[x],t;i;i=e[i].ne)
        {
            t=e[i].to;
            if(t==f||onr[t]) continue;
            dfs1(t,x);
            dpd[x]+=dpd[t]+e[i].w;
        }
        if(sc[x]>eps) dpd[x]/=sc[x];
    }
    void dfs2(int x,int f)
    {
        for(int i=he[x],t;i;i=e[i].ne)
        {
            t=e[i].to;
            if(f==t||onr[t]) continue;
            dpu[t]=e[i].w;
            if(deg[x]-1.0>eps)dpu[t]+=(dpd[x]*sc[x]-e[i].w-dpd[t]+dpu[x]*(deg[x]-sc[x]))/(deg[x]-1.0);
            dfs2(t,x);
        }
    }
    int rnd[N],hp;
    int sp;bool vv[N];
    int find(int x,int f)
    {
        if(vv[x]){sp=x;return 1;}
        vv[x]=1;int tmp;
        for(int i=he[x],t;i;i=e[i].ne)
        {
            t=e[i].to;
            if(t==f) continue;
            if(tmp=find(t,x))
            {
                if(tmp==1)
                {
                    rnd[++hp]=x;
                    onr[x]=1;
                    if(x!=sp) return 1;
                }
                return 2;
            }
        }
        return 0;
    }
    double dpt[N];
    void dfs3(int x,int f,int o,int s)
    {
        if(!o)
        {
            int g=0;
            for(int i=he[x],t;i;i=e[i].ne)
            {
                t=e[i].to;
                if(!onr[t]) continue;
                g++;dfs3(t,x,g,s);
                dpu[x]+=dpt[t]+e[i].w;
            }
            dpu[x]/=2;
            return;
        }
        double tmp=0;
        dpt[x]=0;
        for(int i=he[x],t;i;i=e[i].ne)
        {
            t=e[i].to;
            if(!onr[t]||t==s||t==f) continue;
            dfs3(t,x,o,s);
            dpt[x]+=dpt[t]+e[i].w;
            tmp+=1;
        }
        if(sc[x]+tmp>eps)
        dpt[x]=(dpt[x]+dpd[x]*sc[x])/(sc[x]+tmp);
    }
    
    double ans;
    int xi,yi,wi;
    int main()
    {
        read(n),read(m);
        for(int i=1;i<=m;i++)
        {
            read(xi),read(yi),read(wi);
            addline(xi,yi,wi),addline(yi,xi,wi),deg[xi]+=1,deg[yi]+=1;
        }
        if(m==n-1)
        {
            for(int i=1;i<=n;i++) sc[i]=deg[i]-1;
            sc[1]+=1;
            dfs1(1,0);
            dfs2(1,0);
            for(int i=1;i<=n;i++) ans+=(dpd[i]*sc[i]+dpu[i])/deg[i];
            ans/=n;
            printf("%.5lf
    ",ans);
            return 0;
        }
        find(1,0);
        for(int i=1;i<=n;i++) sc[i]=deg[i]-(onr[i]?2.0:1.0);
        for(int i=1;i<=hp;i++) dfs1(rnd[i],0);
        for(int i=1;i<=hp;i++) dfs3(rnd[i],0,0,rnd[i]);
        for(int i=1;i<=hp;i++) dfs2(rnd[i],0);
        for(int i=1;i<=n;i++) ans+=(dpd[i]*sc[i]+dpu[i]*(deg[i]-sc[i]))/deg[i];
        ans/=n;
        printf("%.5lf
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    数据结构与算法(五):栈
    数据结构与算法(四):线性表二
    数据结构与算法(三):线性表一
    数据结构与算法(二):时间复杂度和空间复杂度
    数据结构与算法(一):什么是数据结构
    数据结构-希尔排序法
    数据结构-插入排序法
    数据结构-选择排序法
    数据结构-冒泡排序法
    数据结构-排序法
  • 原文地址:https://www.cnblogs.com/rikurika/p/11271194.html
Copyright © 2011-2022 走看看