洛谷P2607题解
想要深入学习树形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的答案为:
\]
\]
下图为洛谷秋令营的课件讲解:
关键代码如下:
void covertree(int fr)//寻找基环树
{
used[fr]=1;
for(int i=head[fr];i;i=e[i].next)
{
int to=e[i].to;
if(used[to]==0)
{
covertree(to);
}
}
}
void findcir(int fr,int fa)//寻找基环树中的环
{
if(flag) return ;
vis[fr]=1;
for(int i=head[fr];i;i=e[i].next)
{
int to=e[i].to;
if(vis[to]==0)
{
findcir(to,fr);
}else if(to!=fa)
{
fri=fr;//第一个点
toi=to;//第二个点
E=i;//边的编号
flag=1;
return ;
}
}
}
void DPf(int fr)//以其中的一点为树根做树形DP
{
visf[fr]=1;
f[fr][1]=crit[fr];
for(int i=head[fr];i;i=e[i].next)
{
int to=e[i].to;
if(visf[to]==0&&(i^1)!=E)//保证不会选到第一个点和第二个点,相当于断边
{
DPf(to);
f[fr][0]+=max(f[to][0],f[to][1]);
f[fr][1]+=f[to][0];
}
}
}
void DPg(int fr)//再以另一点为树根再做一次树形DP
{
visg[fr]=1;
g[fr][1]=crit[fr];
for(int i=head[fr];i;i=e[i].next)
{
int to=e[i].to;
if(visg[to]==0&&(i^1)!=E)
{
DPg(to);
g[fr][0]+=max(g[to][0],g[to][1]);
g[fr][1]+=g[to][0];
}
}
}
for(int i=1;i<=n;i++)//调用+统计答案
{
if(used[i]==1) continue;
covertree(i);
flag=0;
findcir(i,-1);
DPf(fri);
DPg(toi);
ans+=max(f[fri][0],g[toi][0]);
}
特别注意:
本题是基环树森林,而不是单棵基环树,故要反复寻找覆盖基环树,最后将所有答案加起来。
因为要断边,所以前向星计数器
ei一定要初始化为 1。- 用多个数组标记(
used[],vis[],visf[],visg[])。 - 一定要注意
f,g和fr,to,不要手快打错了。
- 用多个数组标记(
洛谷P2607题解的更多相关文章
- 【题解】洛谷P2607【ZJOI2008】骑士
洛谷P2607:https://www.luogu.org/problemnew/show/P2607 一道毒瘤的环基树问题 第一次做环基树的题目 刚看题目的时候觉得不就是跟没有上司的舞会一样嘛 然后 ...
- [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码
[洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...
- 「树形DP」洛谷P2607 [ZJOI2008]骑士
P2607 [ZJOI2008]骑士 题面: 题目描述 Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的 ...
- 洛谷P5759题解
本文摘自本人洛谷博客,原文章地址:https://www.luogu.com.cn/blog/cjtb666anran/solution-p5759 \[这道题重在理解题意 \] 选手编号依次为: \ ...
- 关于三目运算符与if语句的效率与洛谷P2704题解
题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...
- c++并查集配合STL MAP的实现(洛谷P2814题解)
不会并查集的话请将此文与我以前写的并查集一同食用. 原题来自洛谷 原题 文字稿在此: 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. ...
- 【洛谷P2607】骑士 没有上司的舞会+
题目大意:给定一个 N 个点的外向树森林,点有点权.从该树中选出若干顶点组成一个集合,满足任意相邻的两个顶点不同时出现在该集合中,求这样集合中点权和的最大值为多少. 题解:与树相比,该题多了环这个结构 ...
- 洛谷 P2607 [ZJOI2008]骑士 解题报告
P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...
- 【洛谷】题解 P1056 【排座椅】
题目链接 因为题目说输入保证会交头接耳的同学前后相邻或者左右相邻,所以一对同学要分开有且只有一条唯一的通道才能把他们分开. 于是可以吧这条通道累加到一个数组里面.应为题目要求纵列的通道和横列的通道条数 ...
随机推荐
- cygwin中修改path变量
1.在家目录建立 .bash_profile 文件. 2.在该文件添加: export PATH=/my/path/:$PATH 3.解释,/my/path/为你要添加的目录,为什么不在.bashrc ...
- Kafka Internals: Consumers
Check out my last article, Kafka Internals: Topics and Partitions to learn about Kafka storage inter ...
- C#读写设置修改调整UVC摄像头画面-倾斜
有时,我们需要在C#代码中对摄像头的倾斜进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...
- Java IO---字节流和字符流
一.IO流简介 流 流是一个抽象概念,Java程序和外部设备(可以是硬盘上的文件,也可以是网络设备)之间的输入输出操作是基于流的. 流就好比水管中的水流,具有流入和流出,类比数据的输入和输出. Jav ...
- 2. vue基础-vue-cli(vue脚手架)
1. 作用 快速创建一个基于webpack模板的项目 2. 安装工具 安装webpack:使用npm全局安装webpack,打开命令行工具,输入 npm install webpack -g,安装 ...
- 07-组件通信、slot插槽
一.组件通信 ① 父 => 子 -- 步骤 1)子组件中通过 props 键接受父组件传值 2)父组件通过 v-bind 向子组件传值 --例子 <!DOCTYPE html> &l ...
- java集合学习(2):Map和HashMap
Map接口 java.util 中的集合类包含 Java 中某些最常用的类.最常用的集合类是 List 和 Map. Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含 ...
- linux如何执行定时任务
前言:最近在做一个前端监控系统,用到分表分库的功能,由于代码上无法做到实时新建表,所以只能够曲线救国,使用linux系统的定时任务来完成. ============================== ...
- MAC安装配置maven环境变量
1.下载maven包: 下载链接:
- Docker 修改容器内的时区
利用docker发布服务,发现 程序用获取的系统时间比正常时间晚了8个小时 进入容器 docker exec -it /bin/sh 查询时间 date -R 发现时区为0时区 解决思路 1.复制相应 ...