# 4707 Point Divide and Conquer

Title Description

answer

It has been determined that the two problems dotted tree tree form, how many points of a binary-tree form can be formed after the merger

Consider if split $ (u, v) $ this edge, it is equivalent to two trees dotted black and white coloring, each finding the same color ancestor, and then form a new two dotted tree

Consider if the connection $ (u, v) $, then it should be is $ u-> rt_u $ and $ v-> rt_v $ two paths can merge together in any order, so consider the tree dp, similar to the transfer backpack

Efficiency: $ (n ^ 2) O $

Code

#include <bits/stdc++.h>
using namespace std;
const int N=5005,P=1e9+7;
int n,hd[N],V[N<<1],nx[N<<1],t,f[N][N],sz[N],c[N][N],g[N][N],F[N];
int X(int x){return x>=P?x-P:x;}
void add(int u,int v){
    nx[++t]=hd[u];V[hd[u]=t]=v;
}
void dfs ( int a, int fr) {
    f[u][sz[u]=1]=1;
    for (int v,i=hd[u];i;i=nx[i]){
        if ((v=V[i])==fr) continue;
        dfs (v, u);
        for (int j=1;j<=sz[u];j++)
            for (int i=0;i<=sz[v];i++)
                (F[i+j]+=1ll*f[u][j]*c[i+j-1][j-1]%P*g[v][i]%P)%=P;
        sz[u]+=sz[v];
        for (int i=1;i<=sz[u];i++)
            f[u][i]=F[i],F[i]=0;
    }
    for (int i=sz[u];~i;i--)
        g[u][i]=(g[u][i+1]+f[u][i])%P;
}
int main () {
    cin>>n;c[0][0]=1;
    for (int i=1;i<=n;i++){
        c[i][0]=1;
        for (int j=1;j<=i;j++)
            c[i][j]=X(c[i-1][j]+c[i-1][j-1]);
    }
    for (int i=1,x,y;i<n;i++)
        scanf("%d%d",&x,&y),add(x,y),add(y,x);
    dfs(1,0);cout<<g[1][0]<<endl;return 0;
}

 

Guess you like

Origin www.cnblogs.com/xjqxjq/p/12283393.html