T1题面:

 输入点数为N一棵树

 求树上长度恰好为K的路径个数

 (n < 1e5, k < 500)

  这是今天的考试题,也是一道假的紫题,因为我一个根本不会dp的蒟蒻只知道状态就一遍A掉了……(然后我当时不会……emm)

  考虑f[i][j]表示点i为根的子树中深度为j的点的个数,初始设置f[i][0] = 1。转移的时候,每搞完一棵子树就用这棵子树内的数据用乘法原理更新ans,然后再把它的贡献累加给根,这样可以保证统计不重不漏。

  也可以用点分治来做。

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #define maxn 50010
  4. using namespace std;
  5. template <typename T>
  6. void read(T &x) {
  7. x = 0;
  8. int f = 1;
  9. char ch = getchar();
  10. while (!isdigit(ch)) {
  11. if (ch == '-')
  12. f = -1;
  13. ch = getchar();
  14. }
  15. while (isdigit(ch)) {
  16. x = x * 10 + (ch ^ 48);
  17. ch = getchar();
  18. }
  19. x *= f;
  20. return;
  21. }
  22. void open_file(string s) {
  23. string In = s + ".in", Out = s + ".out";
  24. freopen(In.c_str(), "r", stdin);
  25. freopen(Out.c_str(), "w", stdout);
  26. }
  27. int head[maxn], top, n, k;
  28. struct E {
  29. int to, nxt;
  30. } edge[maxn << 1];
  31. inline void insert(int u, int v) {
  32. edge[++top] = (E) {v, head[u]};
  33. head[u] = top;
  34. }
  35. int f[maxn][510];//第二维j表示深度为j的点数
  36. long long ans;
  37. void dp(int u, int pre) {
  38. for (int i = head[u]; i; i = edge[i].nxt) {
  39. int v = edge[i].to;
  40. if (v == pre)
  41. continue;
  42. dp(v, u);
  43. for (int i = 0; i < k; ++i) //先统计答案
  44. ans += f[u][i] * f[v][k-i-1];
  45. for (int i = 1; i <= k; ++i) //算贡献
  46. f[u][i] += f[v][i-1];
  47. }
  48. return;
  49. }
  50. int main() {
  51. //  open_file("distance");
  52. read(n), read(k);
  53. int u, v;
  54. for (int i = 1; i < n; ++i) {
  55. read(u), read(v);
  56. insert(u, v), insert(v, u);
  57. }
  58. for (int i = 1; i <= n; ++i)
  59. f[i][0] = 1;
  60. dp(1, 0);
  61. printf("%I64d\n", ans);
  62. return 0;
  63. }

  T2题面就不放了。这是一道树形dp的入门题。

  考虑每个点可以有选与不选两种状态,设f[i][0]表示不选这个点后以该点为根的最大贡献,f[i][1]表示选。我们可以自底向顶转移,有f[u][1] = w[u] + sigma(f[v][0]),f[u][0] = sigma(max(f[v][0], f[v][1])。注意第二个方程中选不选子节点是都可以的,要注意这种比较松的限制可能遗漏。

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #define maxn 6010
  4. template <typename T>
  5. void read(T &x) {
  6. x = 0;
  7. int f = 1;
  8. char ch = getchar();
  9. while (!isdigit(ch)) {
  10. if (ch == '-')
  11. f = -1;
  12. ch = getchar();
  13. }
  14. while (isdigit(ch)) {
  15. x = x * 10 + (ch ^ 48);
  16. ch = getchar();
  17. }
  18. x *= f;
  19. return;
  20. }
  21. using namespace std;
  22. int head[maxn], top;
  23. struct E {
  24. int to, nxt;
  25. } edge[maxn << 1];
  26. inline void insert(int u, int v) {
  27. edge[++top] = (E) {v, head[u]};
  28. head[u] = top;
  29. }
  30. int f[maxn][2], w[maxn], ind[maxn], n, root;
  31. void dp(int u) {
  32. f[u][1] = w[u];
  33. for (int i = head[u]; i; i = edge[i].nxt) {
  34. int v = edge[i].to;
  35. dp(v);
  36. f[u][1] += f[v][0];
  37. f[u][0] += max(f[v][1], f[v][0]);
  38. }
  39. return;
  40. }
  41. int main() {
  42. read(n);
  43. for (int i = 1; i <= n; ++i)
  44. read(w[i]);
  45. int u, v;
  46. for (int i = 1; i < n; ++i) {
  47. read(u), read(v);
  48. insert(v, u);
  49. ++ind[u];
  50. }
  51. for (int i = 1; i <= n; ++i)
  52. if (!ind[i]) {
  53. root = i;
  54. break;
  55. }
  56. dp(root);
  57. printf("%d", max(f[root][0], f[root][1]));
  58. return 0;
  59. }

【树形dp】【CF161D】distance on a tree + 【P1352】没有上司的舞会的更多相关文章

  1. (树形DP入门题)Anniversary party(没有上司的舞会) HDU - 1520

    题意: 有个公司要举行一场晚会.为了让到会的每个人不受他的直接上司约束而能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会再邀请他的直接的上司,但该人的上司的上司,上司的上司的上司等都可以邀请. ...

  2. 洛谷 p1352 没有上司的舞会 题解

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

  3. 洛谷P1352 没有上司的舞会——树形DP

    第一次自己写树形DP的题,发个博客纪念`- 题目来源:P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结 ...

  4. P1352 没有上司的舞会——树形DP入门

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

  5. 洛谷P1352 没有上司的舞会 [2017年5月计划 清北学堂51精英班Day3]

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子 结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职 ...

  6. luogu P1352 没有上司的舞会 x

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

  7. P1352 没有上司的舞会&&树形DP入门

    https://www.luogu.com.cn/problem/P1352 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的 ...

  8. [luogu]P1352 没有上司的舞会[树形DP]

    本Lowbee第一次写树形DP啊,弱...一个变量写错半天没看出来...... 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点 ...

  9. 【树形dp】Bzoj3391 [Usaco2004 Dec]Tree Cutting网络破坏

    Description     约翰意识到贝茜建设网络花费了他巨额的经费,就把她解雇了.贝茜很愤怒,打算狠狠报 复.她打算破坏刚建成的约翰的网络.    约翰的网络是树形的,连接着N(1≤N≤1000 ...

  10. 洛谷 P1352 没有上司的舞会【树形DP】(经典)

    <题目链接> <转载于>>> > 题目描述: 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的 ...

随机推荐

  1. E. Tree Reconstruction 解析(思維)

    Codeforce 1041 E. Tree Reconstruction 解析(思維) 今天我們來看看CF1041E 題目連結 題目 略,請直接看原題 前言 一開始完全搞錯題目意思,還以為每次會刪除 ...

  2. vue自定义指令 默认图片

    /**  * 检测图片是否存在  * @param url  */ function imageIsExist(url) {     return new Promise((resolve) => ...

  3. Luogu P4247 [清华集训2012]序列操作

    题意 给定一个长度为 \(n\) 的序列 \(a\) 和 \(q\) 次操作,每次操作形如以下三种: I a b c,表示将 \([a,b]\) 内的元素加 \(c\). R a b,表示将 \([a ...

  4. 嵌入式linux和stm32嵌入式开发这两者之间有什么关联性

    对于更开始入坑的同学,可能也像我一样搞不清楚两者的区别与联系.现在结合知乎网上的相关资料发一篇文章来具体分析. 基于STM32的开发属于微控制器开发领域,主要开发工具是keil或IAR,这种开发更准确 ...

  5. RabbitMQ的简单封装

    一般在工作中,都是直接使用已经封装好的mq的程序集进行功能开发.所以很多时候都没有去了解rabbitmq到底是如何封装(实现使用的).所以心血来潮,简单记录下自己对rabbitmq的简单封装 整体的思 ...

  6. 浅谈MVP

    MVP是什么 MVP:Model-View-PresenterModel:表示数据提供者:View:表示数据展示:Presenter:是M与V沟通的桥梁. MVP工作方式 UI:告知Presenter ...

  7. Netty源码解析 -- ChannelOutboundBuffer实现与Flush过程

    前面文章说了,ChannelHandlerContext#write只是将数据缓存到ChannelOutboundBuffer,等到ChannelHandlerContext#flush时,再将Cha ...

  8. leetcode113:sudoku-solver

    题目描述 请编写一个程序,给数独中的剩余的空格填写上数字 空格用字符'.'表示 假设给定的数独只有唯一的解法 这盘数独的解法是: 红色表示填上的解 Write a program to solve a ...

  9. layui form表单提交

    layui.use(['form'], function () { var form = layui.form; //监听提交 form.on('submit(formDemo)', function ...

  10. 对“线上问题 不能gdb调试怎么处理??“”的思考

    Q1:线上问题的process 都为release版本!不带调试信息怎么查?(目前有时需要查线上问题, 不得不解决这个问题) 之前查问题都是编译环境编译一个带有debug信息的版本进行替换来调试,但是 ...