找了半天bug 发现把q打成了p。。。

思路:用dp[ i ][ j ][ k ] 表示在 i 这个点 这个点的状态为 j (0:不选 1:属于奇联通块 2:属于偶联通块) 且 奇联通块 - 偶联通块 = k 的方案数, 这个统计的方案数不包括i这个点的联通块。

dp[u][0][x+y]=dp[u][0][x]*dp[v][0][y]+dp[u][0][x]*dp[v][1][y-1]+dp[u][0][x]*dp[v][2][y+1]
dp[u][1][x+y]=dp[u][1][x]*dp[v][0][y]+dp[u][1][x]*dp[v][2][y]+dp[u][2][x]*dp[v][1][y]
dp[u][2][x+y]=dp[u][2][x]*dp[v][0][y]+dp[u][1][x]*dp[v][1][y]+dp[u][2][x]*dp[v][2][y]
 #include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define piii pair<int, pair<int,int> > using namespace std; const int N = + ;
const int M = + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const int zero = ; int n, dp[N][][], tmp[][], down[N], up[N];
vector<int> edge[N]; void inline add(int &x, int y) {
x += y; if(x >= mod) x -= mod;
} void dfs(int u, int p) {
dp[u][][zero] = ;
dp[u][][zero] = ;
up[u] = down[u] = ;
for(int v : edge[u]) {
if(v == p) continue;
dfs(v, u);
memset(tmp, , sizeof(tmp));
for(int p = down[u]; p <= up[u]; p++) {
for(int q = down[v] - ; q <= up[v] + ; q++) {
if((p + q > n) || (p + q < (-n) / - )) continue;
add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero] % mod);
add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero-] % mod);
add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero+] % mod); add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero] % mod);
add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero] % mod);
add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero] % mod); add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero] % mod);
add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero] % mod);
add(tmp[][p+q+zero], 1ll * dp[u][][p+zero] * dp[v][][q+zero] % mod); if(tmp[][p + q + zero]) down[u] = min(down[u], p + q), up[u] = max(up[u], p + q);
if(tmp[][p + q + zero]) down[u] = min(down[u], p + q), up[u] = max(up[u], p + q);
if(tmp[][p + q + zero]) down[u] = min(down[u], p + q), up[u] = max(up[u], p + q);
}
} for(int i = down[u]; i <= up[u]; i++)
for(int j = ; j < ; j++)
dp[u][j][i + zero] = tmp[j][i + zero];
}
} void init() {
for(int i = ; i <= n; i++)
edge[i].clear();
memset(dp, , sizeof(dp));
} int main() {
while(scanf("%d", &n) != EOF) {
init();
for(int i = ; i < n; i++) {
int u, v; scanf("%d%d", &u, &v);
edge[u].push_back(v);
edge[v].push_back(u);
}
dfs(, );
int ans = ;
for(int i = down[]; i <= up[]; i++) {
add(ans, 1ll * max(, i) * dp[][][i + zero] % mod);
add(ans, 1ll * max(, i + ) * dp[][][i + zero] % mod);
add(ans, 1ll * max(, i - ) * dp[][][i + zero] % mod);
}
add(ans, * ans % mod);
printf("%d\n", ans);
}
return ;
}
/*
*/

HDU - 4809 树形dp的更多相关文章

  1. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  2. HDU 1520 树形dp裸题

    1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...

  3. HDU 1561 树形DP入门

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  4. HDU 2196树形DP(2个方向)

    HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...

  5. HDU 1520 树形DP入门

    HDU 1520 [题目链接]HDU 1520 [题目类型]树形DP &题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知 ...

  6. codevs 1380/HDU 1520 树形dp

    1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 回到问题 题目描述 Description Ural大学有N个职员 ...

  7. HDU 5834 [树形dp]

    /* 题意:n个点组成的树,点和边都有权值,当第一次访问某个点的时候获得利益为点的权值 每次经过一条边,丢失利益为边的权值.问从第i个点出发,获得的利益最大是多少. 输入: 测试样例组数T n n个数 ...

  8. hdu 4267 树形DP

    思路:先dfs一下,找出1,n间的路径长度和价值,回溯时将该路径长度和价值清零.那么对剩下的图就可以直接树形dp求解了. #include<iostream> #include<al ...

  9. hdu 4607 (树形DP)

    当时比赛的时候我们找出来只要求出树的最长的边的节点数ans,如果要访问点的个数n小于ans距离直接就是n-1 如果大于的话就是(n-ans)*2+ans-1,当时求树的直径难倒我们了,都不会树形dp ...

随机推荐

  1. ECMAScript6语法检查规范错误信息说明

    项目中使用ECMAScript6的时候经查会使用语法检查,下面是常见错误信息的汇总: “Missing semicolon.” : “缺少分号.”, “Use the function form of ...

  2. 《设计模式》-原则六:迪米特法则(LoD)

    啊哈哈哈哈,又到星期五了,真开心.回来吃完饭慌着去玩游戏,所以立马过来先完成今天的学习目标. 这个原则的命名好像是以某个人的名字命名的,算了我不去管这个了. 直接说说我学到的东西,这个迪米特法则又可以 ...

  3. Concat层解析

    Concat层的作用就是将两个及以上的特征图按照在channel或num维度上进行拼接,并没有eltwise层的运算操作,举个例子,如果说是在channel维度上进行拼接conv_9和deconv_9 ...

  4. 【leetcode 简单】 第六十六题 用栈实现队列

    使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队列是否为空. ...

  5. vue项目的配置

    1.第一首先我们先安装:visual studio code开发环境,可以换成中文版的. 2.安装note.js   下载链接:https://nodejs.org/en/ 3.安装npm使用淘宝镜像 ...

  6. Python练习-一个Break跳出所有循环

    Alex大神的需求:三层循环,在最内层循环中使用break,让所有循环结束; # 编辑者:闫龙 i=1; count=0; while 1==i : while 1==i: while 1==i: c ...

  7. 常见踩坑案例(二)-Request method 'POST' not supported

    一 前言 最近涉及到与前后端的数据对接,按道理来说没一点压力结果被一前端童鞋带坑里去了(不过也是很久没写过这种前后端分离进行联调的事情了,如果是一个人全套弄的话就不会出现下面问题). 二 Reques ...

  8. halcon发布

    1: halcon发布 : 在MFC程序中 添加 #include "include/halcon/cpp/HalconCpp.h"using namespace Halcon;# ...

  9. python基础===一行 Python 代码实现并行(转)

    原文:https://medium.com/building-things-on-the-internet/40e9b2b36148 译文:https://segmentfault.com/a/119 ...

  10. 使用ubifs格式的根文件系统

    配置内核,使其支持ubifs文件系统 1)Device Drivers  --->Memory Technology Device (MTD) support  --->UBI - Uns ...