zoukankan      html  css  js  c++  java
  • Random Access Iterator 2019 ICPC 徐州网络赛(树上概率DP)

    比赛时认为给了根节点输入的点就是根和儿子的顺序了,其实输入是个无向的树,智障了,一直wa,还以为算概率写法错了。一个dfs求深度,一个dfs求dp值就可以了,简单题

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N=1e6+5;
    vector<int>G[N];
    const ll p=1e9+7;
    int n;
    int depth[N];
    ll dp[N];
    int res=0;
    ll quick_pow(ll a, ll b, ll mod)
    {
        ll  r = 1, base = a;
        while (b)
        {
            if (b & 1)
                r = (r*base)% mod;
            base = (base*base) % mod;
            b >>= 1;
        }
        return r;
    }
    void dfs(int u,int d,int fa){
        depth[u]=d;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(v==fa)continue;
            dfs(v,d+1,u);
        }
        res=max(res,d);
    }
    void gao(){
        for(int i=1;i<=n;i++){
            if(depth[i]==res){
                dp[i]=1;
            }
        }
    }
    ll dfs2(int u,int fa){
        if(dp[u]>0)return dp[u]%p;
        ll temp=0;
        int s=G[u].size()-1;
        if(u==1)s++;
        //cout<<u<<" "<<fa<<"  "<<s<<endl;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(v==fa)continue;
            temp=(temp+quick_pow(s,p-2,p)*dfs2(v,u)%p)%p;
        }
        dp[u]=(1-quick_pow((1-temp+p)%p,s,p)+p)%p;
        return dp[u];
    }
    int main()
    {
        scanf("%d",&n);
        int u,v;
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,0,-1);
        gao();
        printf("%lld
    ",dfs2(1,-1));
        return 0;
    }
    不疯魔不成活
  • 相关阅读:
    C++——文件的读写
    我以我血荐轩辕——记徐家福教授的演讲
    文件命名
    面向对象
    关于函数
    php跨域发送请求原理以及同步异步问题
    关于iframe
    关于url
    cookie
    call和apply
  • 原文地址:https://www.cnblogs.com/gzr2018/p/11494330.html
Copyright © 2011-2022 走看看