博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
51Nod1353 树
阅读量:5167 次
发布时间:2019-06-13

本文共 1128 字,大约阅读时间需要 3 分钟。

题意很简单,大概是有多少种删边方法使得每一块大小不小于k

我们设一个树形dp,f[i][j]表示i的子树中,i所在联通块的大小为j的方案数有多少

特别的,我们用f[i][0]表示∑f[i][j] (j>=k)

那么可以写出以下转移:

f[x][i+j]+=f[x][i]*f[v][j] (j>0)

f[x][i]=f[x][i]*f[v][0]

答案就是f[root][0]

#include
#include
#include
#include
#define LL long long#define M 1000000007using namespace std;struct edge{
int v,nt; } G[4010];int h[2010],f[2010][2010],sz[2010],n,m,cnt=0;inline void ad(int& x,LL y){
x=(x+y)%M; }inline void adj(int x,int y){
G[++cnt]=(edge){
y,h[x]}; h[x]=cnt; G[++cnt]=(edge){
x,h[y]}; h[y]=cnt;}void dp(int x,int p){
f[x][1]=sz[x]=1; for(int v,i=h[x];i;i=G[i].nt) if((v=G[i].v)!=p){
dp(v,x); for(int i=sz[x];i;--i){
for(int j=sz[v];j;--j) ad(f[x][i+j],(LL)f[x][i]*f[v][j]); f[x][i]=(LL)f[x][i]*f[v][0]%M; } sz[x]+=sz[v]; } for(int i=m;i<=sz[x];++i) ad(f[x][0],f[x][i]);}int main(){
scanf("%d%d",&n,&m); for(int x,y,i=1;i

转载于:https://www.cnblogs.com/Extended-Ash/p/9477089.html

你可能感兴趣的文章
打包iOS应用程序
查看>>
EasyUI - DataGrid 去右边空白滚动条列
查看>>
安卓数据库操作
查看>>
MySql中的变量定义
查看>>
spoj2798 QTREE3 Query on a tree again!
查看>>
Python acos() 函数
查看>>
top coder password题解
查看>>
Myeclipse 安装所有插件
查看>>
4-1
查看>>
POJ - 2796 Feel Good 单调递增栈+前缀和
查看>>
redis面试题
查看>>
三、activiti designer 的安装
查看>>
Python自省
查看>>
How to Choose the Best Way to Pass Multiple Models in ASP.NET MVC
查看>>
【算法】求二叉树各路径结点之和并找出最大值的路径
查看>>
c 字符串 函数
查看>>
12.5 站立会议
查看>>
SQLServer数据库的一些全局变量
查看>>
Centos-本机网络连接、运行端口和路由表等信息-netstat
查看>>
胡适阅读
查看>>