传送门

题意:给定一棵树,把一些节点染黑,使任意节点到离它最近黑点的距离不超过k
思路:
这是一道个人认为比较好玩但也比较难写的题目
看到这个数据范围,其实还是挺蛋疼的,因为CF的机子你也不知道能跑多快
看了下status,AC程序的状态貌似挺多,但是大同小异
如果一个点到离它最近黑点的距离大于k,那么我们称它为未覆盖点
我写的状态是
f[i][0/1][j]f[i][0/1][j]表示i的子树中,与i距离最远的未覆盖点和i的距离为j/与i距离最近的染色点和i的距离为j,0/1状态分别表示前后者
起初我想的转移是枚举每棵子树中最远的未覆盖点/最近的染色点,以此确定状态进行转移,由于这种转移要枚举所有子树,所以我改成了vector作邻接表
一开始有些zz,本来是正确的状态,但被聪爷爷往沟里带多加了一维导致转移极为繁琐
还好改了回来
比较容易进行分开讨论
0状态的转移就是子树状态为0或者状态为1,但黑点染不到最远的0点
1状态的转移就是子树状态为1或者状态为0,黑点可以染到最远的0点
特殊处理f[x][0][0]f[x][0][0]和f[x][1][0]f[x][1][0]
然后就转移成了一坨
每次转移要枚举当前子树v和它的j,还要枚举其它子树和它们的j,所以时间复杂度是O(n2k2)O(n^2k^2)

#include<cstdio>
#include<iostream>
#include<vector>
#define mo 1000000007
using namespace std;
int n,m,tot;
int f[105][2][105];
vector<int> e[105];
void dfs(int x,int fa)
{f[x][1][0]=1;f[x][0][0]=1;int v;for (int i=0;i<e[x].size();++i)if (e[x][i]!=fa){v=e[x][i];dfs(v,x);//f[x][0][j]表示x子树有不在掌控范围内的点,离x最远距离为j //f[x][1][j]表示x子树都被掌控了,离x最近的黑色距离为j //父亲影响子树,子树影响父亲,子树影响子树 f[x][0][0]=1LL*f[x][0][0]*f[v][1][m]%mo;int t=0;//如果x染成黑色 for (int j=0;j<=m;++j) t=(t+f[v][1][j])%mo;for (int j=0;j<m;++j) t=(t+f[v][0][j])%mo;f[x][1][0]=1LL*f[x][1][0]*t%mo;}for (int i=0;i<e[x].size();++i)if (e[x][i]!=fa){for (int j=0;j<m-1;++j){v=e[x][i];int t=f[v][0][j];for (int k=0;k<i;++k)if (e[x][k]!=fa){int p=0;for (int l=0;l<=j;++l) p=(p+f[e[x][k]][0][l])%mo;for (int l=m-j-1;l<=m;++l) p=(p+f[e[x][k]][1][l])%mo;t=1LL*t*p%mo;}for (int k=i+1;k<e[x].size();++k)if (e[x][k]!=fa){int p=0;for (int l=0;l<j;++l) p=(p+f[e[x][k]][0][l])%mo;for (int l=m-j-1;l<=m;++l) p=(p+f[e[x][k]][1][l])%mo;t=1LL*t*p%mo;}(f[x][0][j+1]+=t)%=mo;}for (int j=0;j<m;++j){v=e[x][i];int t=f[v][1][j];for (int k=0;k<i;++k)if (e[x][k]!=fa){int p=0;for (int l=0;l<m-j-1;++l) p=(p+f[e[x][k]][0][l])%mo;for (int l=j;l<=m;++l) p=(p+f[e[x][k]][1][l])%mo;t=1LL*t*p%mo;}for (int k=i+1;k<e[x].size();++k)if (e[x][k]!=fa){int p=0;for (int l=0;l<m-j-1;++l) p=(p+f[e[x][k]][0][l])%mo;for (int l=j+1;l<=m;++l) p=(p+f[e[x][k]][1][l])%mo;t=1LL*t*p%mo;}(f[x][1][j+1]+=t)%=mo;}}
}
main()
{scanf("%d%d",&n,&m);for (int x,y,i=1;i<n;++i)scanf("%d%d",&x,&y),e[x].push_back(y),e[y].push_back(x);dfs(1,0);int ans=0;for (int i=0;i<=m;++i) ans=(ans+f[1][1][i])%mo;printf("%d\n",ans);
}

显然上面的转移比较繁琐,循环嵌套较多,还要考虑特判
考虑优化
能不能不枚举其它子树呢?
答案当然是可以的
状态还是一样
假设当前节点为x,枚举到子节点v
分成6种情况考虑
x状态为1,v状态为1(直接比较谁的黑点更近即可)
x状态为1,v状态为0,但是x中的黑点可以影响到v中的未覆盖点
x状态为1,v状态为0,但是x中的黑点不能影响到v中的未覆盖点
x状态为0,v状态为0(直接比较谁的未覆盖点更近即可)
x状态为0,v状态为1,但是v中的黑点可以影响到x中的未覆盖点
x状态为0,v状态为1,但是v中的黑点不能影响到x中的未覆盖点
这样一来就要比上面的程序清晰多了,而且时间复杂度也比较优秀:O(nk2)O(nk^2)
注意范围和边界情况

#include<cstdio>
#include<iostream>
#include<vector>
#define mo 1000000007
using namespace std;
int n,m,tot;
int f[105][2][105],g[105][2][105];
vector<int> e[105];
void dfs(int x,int fa)
{f[x][1][0]=1;f[x][0][0]=1;int v;  for (int i=0;i<e[x].size();++i)if (e[x][i]!=fa){v=e[x][i];dfs(v,x);for (int j=0;j<=m;++j) g[x][0][j]=0,g[x][1][j]=0;for (int j=0;j<=m;++j){for (int k=0;k<=m;++k)g[x][1][min(j,k+1)]=(g[x][1][min(j,k+1)]+1LL*f[v][1][k]*f[x][1][j]%mo)%mo;for (int k=0;k<m-j;++k)g[x][1][j]=(g[x][1][j]+1LL*f[v][0][k]*f[x][1][j]%mo)%mo;for (int k=m-j;k<=m;++k)g[x][0][k+1]=(g[x][0][k+1]+1LL*f[v][0][k]*f[x][1][j]%mo)%mo;}for (int j=0;j<m;++j){for (int k=0;k<m-1;++k)g[x][0][max(j,k+1)]=(g[x][0][max(j,k+1)]+1LL*f[v][0][k]*f[x][0][j]%mo)%mo;for (int k=0;k<m-j;++k)g[x][1][k+1]=(g[x][1][k+1]+1LL*f[v][1][k]*f[x][0][j]%mo)%mo;for (int k=m-j;k<=m;++k)g[x][0][j]=(g[x][0][j]+1LL*f[v][1][k]*f[x][0][j]%mo)%mo;}for (int j=0;j<m;++j) f[x][0][j]=g[x][0][j];for (int j=0;j<=m;++j) f[x][1][j]=g[x][1][j];}
}
main()
{scanf("%d%d",&n,&m);for (int x,y,i=1;i<n;++i)scanf("%d%d",&x,&y),e[x].push_back(y),e[y].push_back(x);dfs(1,0);int ans=0;for (int i=0;i<=m;++i) ans=(ans+f[1][1][i])%mo;printf("%d\n",ans);
}

【CF 736C】Ostap and Tree,树形DP相关推荐

  1. CF 1646D Weight the Tree 树形dp

    题目链接 这道题拖了很长时间才去补,今天想起来做这道题 这道题的题意是可以组成合法的点互不相邻,我的思路没有错误,但是赛时没有写出代码,现在想想也觉得可惜,我要是多想到一个度的条件,赛时可能就会过了o ...

  2. 2021牛客多校4 - Rebuild Tree(树形dp)

    题目链接:点击查看 题目大意:给出一棵 nnn 个节点的树,现在可以删掉 kkk 条边,然后加上 kkk 条边,问有多少种方案使得操作后 nnn 个点仍然是一棵树 题目分析:原树删掉 kkk 条边后会 ...

  3. hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)

    题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: ...

  4. HDU 5834 Magic boy Bi Luo with his excited tree 树形DP

    Magic boy Bi Luo with his excited tree 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5834 Descript ...

  5. BZOJ.3227.[SDOI2008]红黑树tree(树形DP 思路)

    BZOJ orz MilkyWay天天做sxt! 首先可以树形DP:\(f[i][j][0/1]\)表示\(i\)个点的子树中,黑高度为\(j\),根节点为红/黑节点的最小红节点数(最大同理). 转移 ...

  6. LiberOJ #6210. 「美团 CodeM 决赛」tree 树形DP

    题目链接:点这里 题解: 需要证明,所求的路径一定是全部权值都为1或者,路径上权值至多有一个为2其余为1且权值2在路径中央. 然后树形DP 设定dp[i][0/1] 以1为根的情况下,以i 节点下子树 ...

  7. Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp

    链接: http://codeforces.com/contest/462/problem/D 题意: 给定n个点的树, 0为根,下面n-1行表示每个点的父节点 最后一行n个数 表示每个点的颜色,0为 ...

  8. VK Cup 2012 Round 1 D. Distance in Tree (树形dp)

    题目:http://codeforces.com/problemset/problem/161/D 题意:给你一棵树,问你两点之间的距离正好等于k的有多少个 思路:这个题目的内存限制首先大一倍,他有5 ...

  9. ARC101E Ribbons on Tree 树形dp 容斥

    题目链接 题意: 给你一棵nnn个点的树,nnn是偶数,把这些点分成n2\frac{n}{2}2n​个点对,每个点对会把路径上的所有边覆盖,问你每条边至少覆盖一次有多少种配对方式.n<=5000 ...

最新文章

  1. 递归删除父节点及所有子节点(转)
  2. 后端:Java 中 10 大坑爹功能!
  3. python输入日期计算天数_用python计算日期(1、返回指定日期所在的一周,2,计算一个日期的月份和天数加减)...
  4. HTML5怎样设置站点,我是怎样让网站用上HTML5 Manifest
  5. 重构16-Encapsulate Conditional(封装条件)
  6. centos7安装docker并设置开机自启以及常用命令
  7. 程序员该如何向奶奶解释 SQL 和 NoSQL?
  8. python登录交换机执行命令_利用Python脚本登录交换机实现自动配置备份的方法
  9. Matlab 之meshgrid interp griddata interp2
  10. 【更新1.0:PoC发布】CVE-2020-1350: Windows DNS Server蠕虫级远程代码执行漏洞通告
  11. 2020-11-07 Mybatis
  12. 理解崩溃和崩溃日志(WWDC 2018 session 414)
  13. 网络安全:图片隐藏攻击
  14. 自动驾驶轨迹预测论文阅读(二)TPNet: Trajectory Proposal Network for Motion Prediction
  15. destoon模板安装方法
  16. 与NC对接传输凭证等数据, xml格式文件传输
  17. rstudio找不到r低版本_R语言安装新版本后旧版本安装包的迁徙问题
  18. 1024程序员节:北京尚学堂向改变世界的程序员致敬
  19. android通知栏使用情况,Android通知栏(Notification)介绍及使用
  20. ffmpeg 处理ts视频流

热门文章

  1. 分布式缓存Redis应用场景解析
  2. 怎么在HTML上显示数据库的表格,在预定义的html表格中显示数据库表格记录
  3. psv应用java_PSV内容管理功能详细说明
  4. ElasticSearch索引
  5. dijkstra伪代码翻译java,Dijkstra算法的伪代码和C语言版本,还是模版
  6. LeetCode-83: 删除排序链表中的重复元素
  7. lan交换和无线教师手册_无线AP组网方式有多种,办公楼的无线覆盖系统的组网方式有哪些?...
  8. 【java基础知识】swagger组件常用命令
  9. 广州大学计算机技术复试c语言试题,广州大学C语言程序设计期末考试试卷含答案...
  10. java 漏洞挖掘_Java反序列化漏洞的挖掘、攻击与防御