想要深入学习树形DP,请点击我的博客


本题的DP模型同 P1352 没有上司的舞会。本题的难点在于如何把基环树DP转化为普通的树上DP。

考虑断边和换根。先找到其中的一个环,在上面随意取两个点, 断开这两个点的边,使其变为一棵普通树。以其中的一点为树根做树形DP,再以另一点为树根再做一次树形DP,因为相邻的两点不能同时选,所以最后统计一下 \(f(i)(0)\) 与 \(g(j)(0)\) 的最大值即可。

定义 \(f(i)(0/1)\) 为第一次树形DP的 \(i\) 点的最优解,\(g(i)(0/1)\) 为第二次树形DP的 \(i\) 点的最优解。$\text{Ans} $ 为一次基环树DP的答案。\(\text{E}_\text{Circle}\) 为基环树的环上的点的集合。

故一次基环树DP的答案为:

\[\text{Ans}=\max\{f(i)(0),g(j)(0)\}
\]

\[(i,j\in \text{E}_\text{Circle},i\neq j)
\]

下图为洛谷秋令营的课件讲解:

关键代码如下:

  1. void covertree(int fr)//寻找基环树
  2. {
  3. used[fr]=1;
  4. for(int i=head[fr];i;i=e[i].next)
  5. {
  6. int to=e[i].to;
  7. if(used[to]==0)
  8. {
  9. covertree(to);
  10. }
  11. }
  12. }
  13. void findcir(int fr,int fa)//寻找基环树中的环
  14. {
  15. if(flag) return ;
  16. vis[fr]=1;
  17. for(int i=head[fr];i;i=e[i].next)
  18. {
  19. int to=e[i].to;
  20. if(vis[to]==0)
  21. {
  22. findcir(to,fr);
  23. }else if(to!=fa)
  24. {
  25. fri=fr;//第一个点
  26. toi=to;//第二个点
  27. E=i;//边的编号
  28. flag=1;
  29. return ;
  30. }
  31. }
  32. }
  33. void DPf(int fr)//以其中的一点为树根做树形DP
  34. {
  35. visf[fr]=1;
  36. f[fr][1]=crit[fr];
  37. for(int i=head[fr];i;i=e[i].next)
  38. {
  39. int to=e[i].to;
  40. if(visf[to]==0&&(i^1)!=E)//保证不会选到第一个点和第二个点,相当于断边
  41. {
  42. DPf(to);
  43. f[fr][0]+=max(f[to][0],f[to][1]);
  44. f[fr][1]+=f[to][0];
  45. }
  46. }
  47. }
  48. void DPg(int fr)//再以另一点为树根再做一次树形DP
  49. {
  50. visg[fr]=1;
  51. g[fr][1]=crit[fr];
  52. for(int i=head[fr];i;i=e[i].next)
  53. {
  54. int to=e[i].to;
  55. if(visg[to]==0&&(i^1)!=E)
  56. {
  57. DPg(to);
  58. g[fr][0]+=max(g[to][0],g[to][1]);
  59. g[fr][1]+=g[to][0];
  60. }
  61. }
  62. }
  63. for(int i=1;i<=n;i++)//调用+统计答案
  64. {
  65. if(used[i]==1) continue;
  66. covertree(i);
  67. flag=0;
  68. findcir(i,-1);
  69. DPf(fri);
  70. DPg(toi);
  71. ans+=max(f[fri][0],g[toi][0]);
  72. }

特别注意

  • 本题是基环树森林,而不是单棵基环树,故要反复寻找覆盖基环树,最后将所有答案加起来。

  • 因为要断边,所以前向星计数器 ei 一定要初始化为 1。

    • 用多个数组标记(used[],vis[],visf[],visg[])。
    • 一定要注意 f,gfr,to,不要手快打错了。

洛谷P2607题解的更多相关文章

  1. 【题解】洛谷P2607【ZJOI2008】骑士

    洛谷P2607:https://www.luogu.org/problemnew/show/P2607 一道毒瘤的环基树问题 第一次做环基树的题目 刚看题目的时候觉得不就是跟没有上司的舞会一样嘛 然后 ...

  2. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  3. 「树形DP」洛谷P2607 [ZJOI2008]骑士

    P2607 [ZJOI2008]骑士 题面: 题目描述 Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的 ...

  4. 洛谷P5759题解

    本文摘自本人洛谷博客,原文章地址:https://www.luogu.com.cn/blog/cjtb666anran/solution-p5759 \[这道题重在理解题意 \] 选手编号依次为: \ ...

  5. 关于三目运算符与if语句的效率与洛谷P2704题解

    题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...

  6. c++并查集配合STL MAP的实现(洛谷P2814题解)

    不会并查集的话请将此文与我以前写的并查集一同食用. 原题来自洛谷 原题 文字稿在此: 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. ...

  7. 【洛谷P2607】骑士 没有上司的舞会+

    题目大意:给定一个 N 个点的外向树森林,点有点权.从该树中选出若干顶点组成一个集合,满足任意相邻的两个顶点不同时出现在该集合中,求这样集合中点权和的最大值为多少. 题解:与树相比,该题多了环这个结构 ...

  8. 洛谷 P2607 [ZJOI2008]骑士 解题报告

    P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...

  9. 【洛谷】题解 P1056 【排座椅】

    题目链接 因为题目说输入保证会交头接耳的同学前后相邻或者左右相邻,所以一对同学要分开有且只有一条唯一的通道才能把他们分开. 于是可以吧这条通道累加到一个数组里面.应为题目要求纵列的通道和横列的通道条数 ...

随机推荐

  1. [Linux] TMUX Python版本设置

    TMUX Python版本设置 本地mac的终端已经设置python版本为python3.7, 结果进入tmux时,一直时python2.7. # 本地.bash_profile alias pyth ...

  2. vue项目的一个package.json

    {   "name": "projectName",   "version": "1.0.1",   "des ...

  3. Java 之 自定义异常

    1.为什么需要自定义异常类 Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开发中总是有些异常情况是没有定义好的,此时我们根据自己业务的异常情况来定义异常类.  一些异常都是 Java ...

  4. Jmeter如何测试接口

    现在对测试人员的要求越来越高,不仅仅要做好功能测试,对接口测试的需求也越来越多!所以也越来越多的同学问,怎样才能做好接口测试? 要真正的做好接口测试,并且弄懂如何测试接口,需要从如下几个方面去分析问题 ...

  5. 第一册:lesson 133.

    原文: Sensational news. question:What reasons did  Karen give for a wanting to retire? Have you just m ...

  6. Maven项目中jstl表达式失效

    从网上看到的可能原因: 1.包没导入 2.web.xml版本太低,不支持 最后,我一直忽略了的解决办法: 关于jstl和el表达式失效的解决办法 - - ITeye博客 https://aazham. ...

  7. Gzip模块

    Gzip模块为python的压缩和解压缩模块,读写gzip 文件 一.使用gzip模块压缩文件: 1 import gzip #导入python gzip模块,注意名字为全小写 2 g = gzip. ...

  8. Centos7 增量备份数据脚本

    #!bin/bash#Automatic Backup Linux System Files#By Author www.jfedu.net#Define VariablesSOURCE_DIR=( ...

  9. 破解CentOS7的root及加密grub修复实战

    破解CentOS7的root及加密grub修复实战 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.破解CentOS7的root口令方案1 1>.启动时任意键暂停启动 2& ...

  10. 了解python-FAQ

    python FAQ 参考: https://docs.python.org/zh-cn/3.7/faq/design.html#why-are-python-strings-immutable wh ...