• codeforces Round #263(div2) D. Appleman and Tree 树形dp


    
    
    
    
    题意:
    给出一棵树,每个节点都被标记了黑或白色,要求把这棵树的其中k条变切换,划分成k+1棵子树,每颗子树必须有1个黑色节点,求有多少种划分方法。
    题解:
    树形dp
    dp[x][0]表示是以x为根的树形成一块不含黑色点的方案数
    dp[x][1]表示是以x为根的树形成一块含一个黑色点方案数
    //зїеп:1085422276
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <queue>
    #include <typeinfo>
    #include <map>
    #include <stack>
    typedef long long ll;
    #define inf 100000000
    #define mod 1000000007
    using namespace std;
    
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    //***************************************
    
    struct ss
    {
    
        int to,next;
    }e[200005*5];
    ll dp[200005][2];
    int head[200005],t,vis[200005],cl[200005];
    void init(){
    memset(head,0,sizeof(head));
    t=1;
    }
    void add(int u,int v)
    {
        e[t].next=head[u];
        e[t].to=v;
        head[u]=t++;
    }
    void dfs(int x,int pre)
    {
        //vis[x]=1;
        dp[x][cl[x]]=1;
        for(int i=head[x];i;i=e[i].next)
        {
            if(e[i].to==pre)continue;
            dfs(e[i].to,x);
            if(cl[x]==1){
                dp[x][1]=(dp[x][1]*dp[e[i].to][0]%mod+dp[x][1]*dp[e[i].to][1])%mod;
            }
            else {
    
                dp[x][1]=(dp[x][1]*dp[e[i].to][0]%mod+dp[x][0]*dp[e[i].to][1]%mod+dp[x][1]*dp[e[i].to][1])%mod;
                dp[x][0]=(dp[x][0]*dp[e[i].to][1]%mod+dp[x][0]*dp[e[i].to][0])%mod;
            }
    
    
        }
    }
    
    int main()
    {
        init();
        int n;
       scanf("%d",&n);
       int x;
       for(int i=0;i<n-1;i++){
        scanf("%d",&x);
        add(i+1,x);
         add(x,i+1);
       }
       for(int i=0;i<n;i++)
        scanf("%d",&cl[i]);
       dfs(0,-1);
       cout<<dp[0][1]<<endl;
        return 0;
    }
    代码
  • 相关阅读:
    mysql dbrd脑裂问题
    iOS 跳转至AppStore评分页面
    UIButton的titleLabe setAttributeSting 首次不起作用
    IOS ScrollView放大缩小点击位置并居中
    UIScrollView 性能优化
    iOS UIButton单双击处理响应不同的方法
    正则表达式过滤手机号
    iOS8通讯录之联系人增删查,多号码增删操作
    CoreData 添加新字段
    一张图教你搞定Mac App Store 应用安装包存储路径
  • 原文地址:https://www.cnblogs.com/zxhl/p/4752922.html
Copyright © 2020-2023  润新知