想要深入学习树形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)
\]

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

关键代码如下:

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,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. 2019 拉卡拉java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.拉卡拉等公司offer,岗位是Java后端开发,因为发展原因最终选择去了拉卡拉,入职一年时间了,也成为了面试官 ...

  2. SpringMVC+EasyUI实现页面左侧导航菜单

    1. 效果图展示 2. 工程目录结构 注意: webapp下的resources目录放置easyui和js(jQuery文件是另外的)                    3. 代码 index.j ...

  3. AppiumLibrary 关键字文档

    http://serhatbolsu.github.io/robotframework-appiumlibrary/AppiumLibrary.html#Start%20Activity

  4. MFC 解决绘图时闪烁问题的一点经验

    2015-05 由于作图过于复杂和频繁,所以时常出现闪烁的情况,一些防止闪烁的方法,如下: (1)将Invalidate()替换为InvalidateRect(). Invalidate()会导致整个 ...

  5. docker下安装redis集群

    docker-compose.yml master: image: redis:4 container_name: redis-cluster_master command: redis-server ...

  6. docker + gitlab + jenkins 搭建 CI/CD 系统

    gitlab+jenkins+docker 计算机网络大全

  7. git 自定义log

    个人记录防止忘记 log别名: git config --global alias.lg=log --color --graph --pretty=format:'%Cred%h%Creset -%C ...

  8. linux设备驱动程序——将驱动程序编译进内核

    linux驱动程序--将驱动程序编译进内核 模块的加载 通常来说,在驱动模块的开发阶段,一般是将模块编译成.ko文件,再使用 sudo insmod module.ko 或者 depmod -a mo ...

  9. PAT 乙级 1002.写出这个数 C++/Java

    1002 写出这个数 (20 分) 题目来源 读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式: 每个测试输入包含 1 个测试用例,即给出自然数 n 的值.这里保证 n ...

  10. PAT 乙级 1040.有几个PAT C++/Java

    题目来源 字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位(P),第 4 位(A),第 6 位(T):第二个 PAT 是第 3 位(P),第 4 位(A),第 6 位( ...