思路

树形dp,设计状态如下:

设 $dp_u_i_0$表示 以点 u 为根的子树 最大匹配数模 m 为 i 时,且 u 点没有匹配的方案数

DP[u][i][1] 表示 以点 u 为根的子树 最大匹配数模 m 为 i 时,且 u 点匹配上的方案数
递推公式如下:
DP[u][k][0](不匹配该节点) +=
  ∑ [i+j==k] 2 * DP[u][i][0] * DP[v][j][1](此时u->v这条边连不连都不会影响到匹配集,所以*2) +
  DP[u][i][0] * DP[v][j][0](儿子已近匹配了)
DP[u][k][1](该节点已经连了边) +=
   ∑ [i+j==k] 2 * DP[u][i][1] * ( DP[v][j][0] + DP[v][j][1] )
DP[u][k][1] (该节点现在正要连边)+=
  ∑ [i+j==k-1(预留出一个位用于匹配)] DP[u][i][0] * DP[v][j][0](此时这条边必须存在并且u,v都不能匹配别的边)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define int long long
#define mod 998244353
#define N 50001
#define M 410
vector vec[N];
int dp[N][M][2],size[N]/*记录节点能最多能匹配多少边*/,temp[M][2]/*dp数组在更新中途不能更改,故用此数组代替*/,m;
void add(int u,int v)//使用边更新数组
{
memset(temp,0,sizeof(temp));
for(int i=0;i<=size[u];i++)//这里时间复杂度可以证明为n*m
{
for(int j=0;j<=size[v];j++)
{
temp[i+j][0]+=2*dp[u][i][0]*dp[v][j][1]+dp[u][i][0]*dp[v][j][0];
temp[i+j][0]%=mod;
temp[i+j][1]+=2*dp[u][i][1]*(dp[v][j][0]+dp[v][j][1]);
temp[i+j][1]%=mod;
temp[i+j+1][1]+=dp[u][i][0]*dp[v][j][0];
temp[i+j+1][1]%=mod;
}
}
for(int i=0;i<m;i++)//将temp复制到dp内
{
dp[u][i][0]=(temp[i][0]+temp[i+m][0])%mod;//i+j有可能超过n
dp[u][i][1]=(temp[i][1]+temp[i+m][1])%mod;
}
size[u]=min(size[u]+size[v],m);//size[u]不能超过m,否则会数组出界。
}
void dfs(int id,int from)
{
size[id]=1;
dp[id][0][0]=1;
for(int i=0;i<vec[id].size();i++)
{
int to=vec[id][i];
if(to==from) continue;
dfs(to,id);//树形dp的惯例,自底向上更新
add(id,to);
}
}
signed main()
{
int n;
cin>>n>>m;
for(int i=1;i<n;i++)
{
int a,b;
scanf("%lld%lld",&a,&b);
vec[a].push_back(b);
vec[b].push_back(a);
}
dfs(1,0);
cout<<(dp[1][0][0]+dp[1][0][1])%mod;
}

  

HDU 6091 - Rikka with Match的更多相关文章

  1. HDU 6091 - Rikka with Match | 2017 Multi-University Training Contest 5

    思路来自 某FXXL 不过复杂度咋算的.. /* HDU 6091 - Rikka with Match [ 树形DP ] | 2017 Multi-University Training Conte ...

  2. HDU 5831 Rikka with Parenthesis II(六花与括号II)

    31 Rikka with Parenthesis II (六花与括号II) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536 ...

  3. 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence

    // 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...

  4. HDU 6088 - Rikka with Rock-paper-scissors | 2017 Multi-University Training Contest 5

    思路和任意模数FFT模板都来自 这里 看了一晚上那篇<再探快速傅里叶变换>还是懵得不行,可能水平还没到- - 只能先存个模板了,这题单模数NTT跑了5.9s,没敢写三模数NTT,可能姿势太 ...

  5. HDU 6093 - Rikka with Number | 2017 Multi-University Training Contest 5

    JAVA+大数搞了一遍- - 不是很麻烦- - /* HDU 6093 - Rikka with Number [ 进制转换,康托展开,大数 ] | 2017 Multi-University Tra ...

  6. HDU 6085 - Rikka with Candies | 2017 Multi-University Training Contest 5

    看了标程的压位,才知道压位也能很容易写- - /* HDU 6085 - Rikka with Candies [ 压位 ] | 2017 Multi-University Training Cont ...

  7. HDU 5828 Rikka with Sequence (线段树)

    Rikka with Sequence 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  8. HDU 5831 Rikka with Parenthesis II (栈+模拟)

    Rikka with Parenthesis II 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5831 Description As we kno ...

  9. hdu 5828 Rikka with Sequence 线段树

    Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

随机推荐

  1. C语言交换两个指针所指位置的数值

    交换指针变量x和y所指向的存储位置处存放的值,不需要第三个位置来存储临时变量.这种方式并没有性能上的优势. void replace(int *x, int *y) { *y = *x ^ *y; * ...

  2. 【题解】保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006]

    [题解]保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006] 传送门:皇宫看守\([LOJ10157]\) 保安站岗 \([P2458]\) \([SDOI2006]\) [题目描述 ...

  3. Java学习:字符串概述与特点

    字符串概述与特点 java.lang.String类 代表字符串 API当中说:Java程序中的所有字符串字面值(如“abc“)都作为此类的实例实现.其实就是说:程序当中所用的双引号字符串,都是Str ...

  4. C#中datatable操作

    //1.新建datatable,为其添加自定义列DataTable dt = new DataTable();dt.Columns.AddRange(new DataColumn[] { new Da ...

  5. TServerSocket组件

    主要作为服务器端的套接字管理器使用.它封装了服务器端的套接字.在打开套接字后,服务器端就处于监听状态,在接收到其它机器的连接请求后,与客户端建立连接,创建一个新的套接字,用于和客户端互传数据,此时TS ...

  6. 我的第一个netcore2.2 api项目搭建(三)

    上一章快速添加了swagger文档管理功能,我的第一个netcore2.2 api项目搭建(二) 这一章实现目标三:api添加身份验证功能 在实现该目标之前,先得理解netcore运行机制. 这是微软 ...

  7. C# vb .NET读取识别条形码线性条码code39

    code39是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取该类型条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速高效.准确 ...

  8. iOS - 什么!iOS13 又获取不到WiFi了

    iOS 12 适配WiFi 增加隐私权限 https://www.cnblogs.com/baitongtong/p/10179519.html ios13又新增定位权限 别的不说,理解请看上篇文章 ...

  9. node.js中使用路由方法

    1.数组的find方法还是不会用,改为filter 2.正规表达式还是理解的不好 //var myrouter = require("./myrouter"); //myroute ...

  10. 87.CSS Flex 弹性盒模型布局教程(共用的css在48篇文章gird)

    CSS Flex 弹性盒模型布局教程 Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. flex布局就是给任何一个容器添加 dis ...