CF 461B - Appleman and Tree(树形DP)

题意:给出一颗树,每个点要么是黑色,要么是白色,设黑点的数量是k,求将树划分成k个子树,并且每颗子树都只有一个黑点的划分方案。

思路:树dp还是很好看出来的,对于一个节点u来说,如果它是黑点,那么就要把它子树中所有包含黑点的子树删掉,如果不是,那么还是要删黑点,但是可以保留一个包含黑点的子树。dp[u]表示处理完u的子树的总方案数,del[u]表示将u的子树中包含黑点的子树都删掉的方案数。那么显然,将u的一个儿子v代表的子树删掉的总方案数为dp[v]+del[v],也就是,要么删掉v的子树,要么删掉u-v这条边。接下来分情况讨论一下就好了,如果u的黑点,结果好计算,如果不是,那么对于一个儿子v代表的子树,要么保留当前的,要么保留之前访问的,将两种方案数加起来就行了。


代码:


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn = 100000+10;
const int mod = 1000000007;
struct Edge
{
    int v,next;
    Edge(int v = 0,int next = 0):v(v),next(next){}
}edges[maxn<<2];
int head[maxn],color[maxn],tcol[maxn],nEdge;
void AddEdges(int u,int v)
{
    edges[++nEdge] = Edge(v,head[u]);
    head[u] = nEdge;
    edges[++nEdge] = Edge(u,head[v]);
    head[v] = nEdge;
}
ll dp[maxn],del[maxn];
void dfs(int u,int fa)
{
    if(color[u])
    {
        dp[u] = 1;
        del[u] = 0;
        tcol[u] = 1;
    }
    else
    {
        dp[u] = 0;
        del[u] = 1;
        tcol[u] = 0;
    }
    for(int k = head[u];k!=-1;k=edges[k].next)
    {
        int v = edges[k].v;
        if(v == fa) continue;
        dfs(v,u);
        if(!tcol[v]) continue;
        tcol[u] += tcol[v];
        if(color[u])
        {
            dp[u] = dp[u]*(dp[v]+del[v])%mod;
        }
        else
        {
            dp[u] = dp[u]*(dp[v]+del[v])%mod + del[u]*dp[v]%mod;
            dp[u] %= mod;
            del[u] = del[u]*(dp[v]+del[v])%mod;
        }
    }
}
int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int n;
    scanf("%d",&n);
    memset(head,0xff,sizeof(head));
    nEdge = -1;
    int u;
    for(int i = 2;i <= n;++i)
    {
        scanf("%d",&u);
        u++;
        AddEdges(u,i);
    }
    for(int i = 1;i <= n;++i)
        scanf("%d",&color[i]);
    dfs(1,-1);
    printf("%I64d\n",dp[1]);
    return 0;
}


你可能感兴趣的:(dp)