P3748 [六省联考 2017] 摧毁“树状图”(树形dp)

Foreword\text{Foreword}Foreword

《小清新》树形 dp。
其实本题没有那么(重读)恶心,但我一开始写完 x=0x=0x=0 后眼瞎没有看到 x=1,2x=1,2x=1,2 时也必然是最优方案(这种东西不黑体吗…)可以直接无视,还在苦苦的写强制选链的特殊情况,被狠狠的恶心到了。
这个故事告诉我们,要仔细审题

感觉自己的做法还是挺舒服的,虽然核心转移看的有些长(也只有 40 行左右),但没有太多的分类讨论,和有些代码枚举儿子然后直接取十几行 max⁡\maxmax 相比感觉更加阳间。

Solution\text{Solution}Solution

题意算比较简洁清晰了,再具体一些大概就是选出两条可重点不可重边的链,将树分割成尽可能多的连通块。

(一开始我受 希望 那个题的影响,尝试了好一会用度数和点数简洁的表示出连通块数目来简化 dp,其实是在玩泥巴,直接做就很方便。)

Definition\text{Definition}Definition

设置状态 fx,i,df_{x,i,d}fx,i,d 表示 xxx 节点子树内选择了 iii已经确定的链,子树内 的联通块最大数目。
ddd 的定义有些复杂:
xxx 作为父亲的时候,d∈[0,4]d\in [0,4]d[0,4] 表示的是 xxx 被删除,与 xxx 相连的儿子的个数,d=5d=5d=5 表示 xxx 不被删除
xxx 作为儿子的时候,d∈[0,1]d\in [0,1]d[0,1] 表示 xxx 被删除,且与父亲相连/不相连。d=5d=5d=5 表示 xxx 不被删除

Transfer\text{Transfer}Transfer

Part 1

d=5d=5d=5xxx 不删时:xxx 必然不会和儿子相连,儿子要么删了但不和父亲连(d=0d=0d=0),要么根本不删 (d=5d=5d=5),不删的时候由于父子都不删,两个联通块合并成一个,所以答案要减一。
fx,i,5+fson,j,5−1→fx,i+j,5f_{x,i,5}+f_{son,j,5}-1\to f_{x,i+j,5}fx,i,5+fson,j,51fx,i+j,5
fx,i,5+fson,j,0→fx,i+j,5f_{x,i,5}+f_{son,j,0}\to f_{x,i+j,5}fx,i,5+fson,j,0fx,i+j,5
d∈[0,4]d\in[0,4]d[0,4] 时:xxx 可以和儿子相连也可以不连,不连的时候儿子是否删除都可以,对应转移分别就是:
fx,i,d+fson,j,1→fx,i+j,d+1f_{x,i,d}+f_{son,j,1}\to f_{x,i+j,d+1}fx,i,d+fson,j,1fx,i+j,d+1
fx,i,d+fson,j,0→fx,i+j,df_{x,i,d}+f_{son,j,0}\to f_{x,i+j,d}fx,i,d+fson,j,0fx,i+j,d
fx,i,d+fson,j,5→fx,i+j,df_{x,i,d}+f_{son,j,5}\to f_{x,i+j,d}fx,i,d+fson,j,5fx,i+j,d
这样 xxx 从所有儿子得到的转移就全完事了,接下来我们需要把 fx,i,df_{x,i,d}fx,i,dddd 的定义从“父亲形态”转化成“儿子形态”,以使它可以继续向父亲转移。

Part 2

d=5d=5d=5 时:xxx 没选就是没选,没什么好说的。
fx,i,5→fx,i,5f_{x,i,5}\to f_{x,i,5}fx,i,5fx,i,5
d=0d=0d=0 时:注意我们之前是强制让 xxx 被删除的,所以我们不能直接让它转移到 fx,i,0f_{x,i,0}fx,i,0。为了删除它,要么使其单独一个点成链,要么让它成为链尾和父亲相连,对应就是:
fx,i,0→fx,i+1,0f_{x,i,0}\to f_{x,i+1,0}fx,i,0fx,i+1,0
fx,i,0→fx,i,1f_{x,i,0}\to f_{x,i,1}fx,i,0fx,i,1

d=2/4d=2/4d=2/4 时:向 xxx 连接的偶数条边必然两两成链:
fx,i,d→fx,i+d/2,0f_{x,i,d}\to f_{x,i+d/2,0}fx,i,dfx,i+d/2,0
d=1/3d=1/3d=1/3 时:单出来的一条可以把 xxx 当成链头停止,也可以继续向父亲延伸:
fx,i,d→fx,i+d/2+1,0f_{x,i,d}\to f_{x,i+d/2+1,0}fx,i,dfx,i+d/2+1,0
fx,i,d→fx,i+d/2,1f_{x,i,d}\to f_{x,i+d/2,1}fx,i,dfx,i+d/2,1

Part 3

这样看起来就做完了?
但是你一测发现过不去样例!
仔细一看,是被两个点一条边的情况 hackhackhack 了。
一般的,当一个图长成深度为 1 的菊花的时候,我们都会出问题。
我们缺少了在一个点连续摆烂的情况。
这个东西有两种解决方案:
第一种是xxx 被删除的时候,可以原地多选几条链,即:
fx,i,0→fx,i+1,0f_{x,i,0}\to f_{x,i+1,0}fx,i,0fx,i+1,0
fx,i,1→fx,i+1,1f_{x,i,1}\to f_{x,i+1,1}fx,i,1fx,i+1,1
第二种是求出度数最大点的度数,让答案和这个度数取个 max⁡\maxmax
第二种虽然看起来更加简单,跑起来也稍微快一点,但如果在考场上,本人还是建议第一种,毕竟多说多错,直接给一个合法转移,让 std::max 做决策而不是自己归纳贪心,肯定更加稳妥。
如果是做练习当然就精益求精啦。

Code\text{Code}Code

代码就简单了,把上面的转移敲出来即可。
(滚动数组无脑好用,不会互相转移出 bug,强推)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=1e5+100;
const int M=2e5+100;
const int inf=1e9;inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n;
int f[N][3][6];
int tmp[2][3][6],now,pre;
vector<int>v[N];
inline void Max(int &x,int y){y>x?x=y:0;return;
}
void dfs(int x,int fa){for(int to:v[x]){if(to==fa||vis[to]) continue;dfs(to,x);}now=1;pre=0;memset(tmp,-0x3f,sizeof(tmp));tmp[now][0][5]=1;tmp[now][0][0]=0;for(int s:v[x]){if(s==fa||vis[s]) continue;swap(now,pre);memset(tmp[now],-0x3f,sizeof(tmp[now]));for(int i=0;i<=2;i++){for(int j=0;i+j<=2;j++){Max(tmp[now][i+j][5],tmp[pre][i][5]+f[s][j][5]-1);Max(tmp[now][i+j][5],tmp[pre][i][5]+f[s][j][0]);for(int d=0;d<=4;d++){Max(tmp[now][i+j][d],tmp[pre][i][d]+f[s][j][0]);Max(tmp[now][i+j][d],tmp[pre][i][d]+f[s][j][5]);if(d+1<=4)Max(tmp[now][i+j][d+1],tmp[pre][i][d]+f[s][j][1]);}}   }}memset(f[x],-0x3f,sizeof(f[x]));for(int i=0;i<=2;i++){Max(f[x][i][5],tmp[now][i][5]);if(i+1<=2) Max(f[x][i+1][0],tmp[now][i][0]);Max(f[x][i][1],tmp[now][i][0]);for(int j=1;j<=4;j++){if(j&1){if(i+j/2<=2) Max(f[x][i+j/2][1],tmp[now][i][j]);if(i+(j+1)/2<=2) Max(f[x][i+(j+1)/2][0],tmp[now][i][j]);}else if(i+j/2<=2) Max(f[x][i+j/2][0],tmp[now][i][j]);}}for(int i=1;i<=2;i++){Max(f[x][i][0],f[x][i-1][0]);Max(f[x][i][1],f[x][i-1][1]);}return;
}
void work0(){for(int i=1;i<n;i++){int x=read(),y=read();v[x].push_back(y);v[y].push_back(x);}dfs(1,0);printf("%d\n",max(f[1][2][0],f[1][2][5]));return;
}
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifint T=read(),op=read();while(T--){n=read();for(int i=1;i<=op;i++) read(),read();work0();for(int i=1;i<=n;i++) v[i].clear();}return 0;
}
/*
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软4年后重登市值第一,纳德拉如何做到的?

他用4年多时间将微软的市值提高了5000亿美元&#xff0c;超越苹果再次成为全球市值最高的上市公司。译 | 达达萨提亚纳德拉&#xff08;Satya Nadella&#xff09;2014年刚刚执掌微软时&#xff0c;微软当时是一个日渐没落的帝国。但在他领导的4年多时间里&#xff0c;微软百花…

[AtCoder Regular Contest 124E] Pass to Next(dp+数学)

ARC 124 E Pass to Nextproblemsolutioncodeproblem 题目链接 solution 令 ci:c_i:ci​: 第 iii 个人传给下一个人球的个数 当 min⁡{ci}≠0\min\{c_i\}\neq 0min{ci​}​0 时&#xff0c;将每一个 cic_ici​ 都减小 111&#xff0c;显然答案序列并不会改变 所以&#x…

P2015 二叉苹果树

P2015 二叉苹果树 题意&#xff1a; 一个完全二叉树&#xff0c;n个点&#xff0c;n-1个边&#xff0c;每个边都有边权&#xff0c;问保留q个边&#xff0c;所能保留的最大边权是多少 题解&#xff1a; 树形dp dp[u][i]表示u的子树上保留i条边&#xff0c;至多保留的苹果数…

P4384 [八省联考 2018] 制胡窜(SAM)

Foreword\text{Foreword}Foreword 人都道正难则反&#xff0c;我偏说正也不难。 这里介绍一种正面直接统计的做法。 和补集做法相比&#xff0c;没有那么多的分类讨论&#xff0c;更多的是对问题的正向分析和逐层化简、转化&#xff0c;也并不麻烦。 由于需要写很多线段树的操作…

【.NET Core项目实战-统一认证平台】第十五章 网关篇-使用二级缓存提升性能

首先说声抱歉&#xff0c;可能是因为假期综合症&#xff08;其实就是因为懒哈&#xff09;的原因&#xff0c;已经很长时间没更新博客了&#xff0c;现在也调整的差不多了&#xff0c;准备还是以每周1-2篇的进度来更新博客&#xff0c;并完成本项目所有功能。言归正传&#xff…

树上子链(树形dp求树的直径)

树上子链 题意&#xff1a; 给定一棵树 T &#xff0c;树 T 上每个点都有一个权值。 定义一颗树的子链的大小为&#xff1a;这个子链上所有结点的权值和 。 请在树 T 中找出一条最大的子链并输出。 题解&#xff1a; 求树的直径&#xff0c;题目中存在负权值&#xff0c;树…

【无码专区1】简单路径的第二大边权(启发式合并+最小生成树)

只有std&#xff0c;没有自我实现&#xff0c;所以叫做无码专区 description 给一张无向图&#xff0c;多次询问&#xff0c;每次询问两个点之间所有简单路径&#xff08;不重复经过点&#xff09;中边权第二大&#xff08;不是严格第二大&#xff09;的权值的最小值。 数据…

# CF1572B Xor of 3(构造)

解析 你CF还是你CF 省选刷到2017再往前不是很想做了&#xff0c;就来CF玩一玩。 再次感受到被CF浅颜色构造虐的快感。 本题靠着各种乱搞特判在WA了无数次之后艹过去了。 根本没有什么正确性的玄学做法&#xff0c;但是看CF数据似乎把 nnn 较小的所有情况全都pia到数据里了&…

NET Core微服务之路:简单谈谈对ELK,Splunk,Exceptionless统一日志收集中心的心得体会...

前言日志&#xff0c;一直以来都是开发人员和运维人员最关心的问题。开发人员可通过日志记录来协助问题定位&#xff0c;运维人员可通过日志发现系统隐患&#xff0c;故障等定位问题。如果你的系统中没有日志&#xff0c;就像一个断了线的风筝&#xff0c;你永远不知道它会的落…

【无码专区2】序列划分(数学)

有std&#xff0c;但是没有自我实现&#xff0c;所以是无码专区 description 完全由数字组成的字符串 sss&#xff0c;划分成若干段&#xff0c;每一段看成一个十进制的数&#xff08;允许前导零&#xff09;求有多少种划分方法使得相邻两个数至少一个是 DDD 的倍数。对 1097…

Rinne Loves Edges

Rinne Loves Edges 题意&#xff1a; 有n给点&#xff0c;m个边&#xff0c;每个边有边权&#xff0c;给你一个点S&#xff0c;问最少花多少代价&#xff0c;可以让叶子节点无法与S点连通 题解&#xff1a; dp[u]:表示u到叶子节点的最短费用的和 dp[u]min(dp[v],w); 代码&…

.NET Core 中的 Generic Host快速使用指南

本文以自己在工作中学习和使用.net core generic-host 作一个总结。前言在创建的ASPNETCORE项目中&#xff0c;我们可以在Main()中看见&#xff0c;我们通过IWebHostBuild创建了一个IWebHost&#xff0c;而微软提供了WebHost.CreateDefaultBuilder(args)来帮助我们更轻松得创建…

CF1580B Mathematics Curriculum(笛卡尔树、树形dp)

解析 比较巧妙的一道题。 难点在于对题意的转化。 关键性质&#xff1a;符合要求的点等价于与笛卡尔树上深度为 mmm 的点。 原因也较为显然&#xff0c;考虑一个特定的点 xxx&#xff0c;当枚举全局最大值时&#xff0c;其会对 xxx 产生贡献&#xff0c;且最大值另一侧就和 xx…

CF1368G Shifting Dominoes(扫描线求矩阵的并集)

CF1368G Shifting Dominoesproblemsolutioncodeproblem 题目链接 solution 求的是最后棋盘本质不同的个数&#xff0c;而本质不同等价于两个空格位置不同。 如果想要移动一个多米诺骨牌&#xff0c;要求长边上下方有空位。 移动可以看成空位的移动。 所以我们考虑把一个 …

吉吉王国(二分+树形dp)

吉吉王国 题意&#xff1a; n个点&#xff0c;m个边&#xff0c;有边权&#xff0c;现在要求叶子节点无法与1号点连通&#xff0c;要求切断的总长度不能超过m&#xff0c;且切断的最长的长度尽可能断 题解&#xff1a; 题意的前半部分可以确定是树形dp&#xff0c;后半部分…

P3239 [HNOI2015]亚瑟王(期望)

解析 显然可以利用期望的线性性对每张牌单独计算贡献。 现在的关键就是如何求出每张牌被使用的概率。 考虑第 iii 张牌&#xff0c;如果它的前面 [1,i−1][1,i-1][1,i−1] 中有 jjj 张牌被使用&#xff0c;那么它被使用的概率就是 1−(1−pi)r−j1-(1-p_i)^{r-j}1−(1−pi​)…

微软一顿操作猛如虎,PowerShell 排名直线上升

近日&#xff0c;TIOBE 发布了 2019 年 3 月编程语言排行榜&#xff0c;PowerShell 首次进入到了榜单的 Top 50 中&#xff0c;排在第 45 位。PowerShell 是运行在 Windows 操作系统上实现对系统以及应用程序进行管理自动化的命令行脚本环境。&#xff08;PowerShell 排在了 TI…

CF1237F Balanced Domino Placements(dp+组合计数)

CF1237F Balanced Domino Placementsproblemsolutioncodeproblem 题目链接 solution 骨牌横着放会占用一行两列&#xff0c;骨牌竖着放会占用两行一列。 问题可以抽象为&#xff1a;每次可以选择连续的两行放 AAA&#xff0c;或选一行放 BBB&#xff1b;每次可以选一列放 B…

AcWing 201. 可见的点

AcWing 201. 可见的点 题意&#xff1a; 题解&#xff1a; 我们先说结论:坐标(i,j)&#xff0c;如果i和j互质&#xff0c;说明该坐标为可见 为什么&#xff1f; 我们想想什么样的坐标可见&#xff0c;什么样的会被挡住。光线是一个直线&#xff0c;在同一个直线上的点会被第一…

模板:LGV引理(线性代数)

所谓LGV引理&#xff0c;就是解决LGV问题的引理。 &#xff08;逃&#xff09; 前言 上联&#xff1a;古有学完SAM学PAM&#xff1b; 下联&#xff1a;今有学完Polya学LGV&#xff1b; 横批&#xff1a;小清新。 常被用于有向图不交路径计数问题。&#xff08;废话&#xff…