首先只要得到 \(x=0\) 时的答案,就可以 \(AC\) 本题。这是很重要的。

考虑由于不能有重复经过的边,所以两路径交点数量 \(\le 1\)。

容易想到设 \(dp_u\) 表示以 \(u\) 为端点的链中的贡献最大值。考虑换根 \(dp\),所以先设它只表示它子树内的部分。

当交点数量 \(=1\) 时,显然可以理解为从一个节点出发的 \(0-4\) 条链,要这些链产生的贡献最大,所以要维护每个点的前四大链,这里的大指 \(dp\) 值大。

当交点数量 \(=0\) 时,可以看作是子树内有一条链,子树外有一条链的情况。

那么首先必须要维护前四大链 \(mx_{x,0/1/2/3}\)。

其次由于删掉一个点会产生儿子 \(+1\) 那么多个联通块,所以还要维护儿子数量 \(cnt_i\)。

考虑到子树内有一条链也得维护,所以得维护 \(f_i\) 表示过子树根的路径最大贡献,\(g_i\) 表示不一定过子树根的路径最大贡献。

由于 \(g_i\) 不好维护,所以再设 \(d_i\) 表示我们认为删掉 \(i\) 后 \(i\) 外还有联通块时,路径的最大贡献。那么就有:

\[\begin{cases}
dp_x=cnt_i+\max(0,mx_{x,0}-1)\\
f_x=\max(dp_x,mx_{x,0}+mx_{x,1}+cnt_x-2)\\
g_x=\max(\max\limits_{y\in sn_x}d_y,f_x)\\
d_x=\max(\max\limits_{y\in sn_x}d_y,f_x+1)
\end{cases}
\]

\(\max\limits_{y\in sn_x}d_y\) 可以通过预处理得到。换根时式子相同,所有定义中“子树内”全部改为“以该点为根的树”即可。

时间复杂度 \(O(tn)\)。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,ans,mx[N][5],fmx[N][3];
int t,id,f[N],dp[N],g[N],d[N];
vector<int>ve[N];
void add(int x,int v){
mx[x][4]=v;
for(int i=3;~i;i--)
if(mx[x][i+1]>mx[x][i])
swap(mx[x][i+1],mx[x][i]);
}void adf(int x,int v){
fmx[x][2]=v;
for(int i=1;~i;i--)
if(fmx[x][i+1]>fmx[x][i])
swap(fmx[x][i+1],fmx[x][i]);
}void dfs1(int x,int fa){
int cnt=ve[x].size()-1;
for(auto y:ve[x]) if(y!=fa)
dfs1(y,x),add(x,dp[y]),adf(x,d[y]);
dp[x]=cnt+max(1,mx[x][0])-1;
f[x]=max(dp[x],mx[x][0]+mx[x][1]+cnt-2);
g[x]=max(fmx[x][0],f[x]);
d[x]=max(fmx[x][0],f[x]+1);
}void dfs2(int x,int fa){
int sz=ve[x].size(),cnt=sz-1;
for(int i=0;i<5;i++)
ans=max(ans,sz),sz+=mx[x][i]-1;
for(auto y:ve[x]){
if(y==fa) continue;
int mo=mx[x][0]+mx[x][1];
int mz=mx[x][0],mt=fmx[x][0];
if(dp[y]==mx[x][0])
mo+=mx[x][2]-mz,mz=mx[x][1];
if(dp[y]==mx[x][1]) mo=mz+mx[x][2];
if(fmx[x][0]==d[y]) mt=fmx[x][1];
dp[x]=cnt+max(1,mz)-1;
f[x]=max(dp[x],mo+cnt-2),add(y,dp[x]);
g[x]=max(mt,f[x]),d[x]=max(mt,f[x]+1);
adf(y,d[x]),ans=max(ans,g[x]+f[y]),dfs2(y,x);
}
}void solve(){
for(int i=1;i<=n;i++){
ve[i].clear(),g[i]=d[i]=f[i]=dp[i]=0;
mx[i][0]=mx[i][1]=mx[i][2]=mx[i][3]=0;
fmx[i][0]=fmx[i][1]=0;
}cin>>n;int tmp;
for(int i=0;i<id*2;i++) cin>>tmp;
for(int i=1,x,y;i<n;i++)
cin>>x>>y,ve[x].push_back(y),ve[y].push_back(x);
ans=0,dfs1(1,0),dfs2(1,0),cout<<ans<<"\n";
}int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t>>id;
while(t--) solve();
return 0;
}

[SHOI2017] 摧毁“树状图”的更多相关文章

  1. bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]

    4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...

  2. bzoj 4871: [Shoi2017]摧毁“树状图”

    4871: [Shoi2017]摧毁“树状图” Time Limit: 25 Sec  Memory Limit: 512 MBSubmit: 53  Solved: 9[Submit][Status ...

  3. BZOJ4871 Shoi2017摧毁“树状图”(树形dp)

    设f[i][0/1/2/3/4/5]表示i子树中选一条链不包含根/i子树中选一条链包含根但不能继续向上延伸/i子树中选一条链可以继续向上延伸/选两条链不包含根/选两条链包含根但不能继续向上延伸/选两条 ...

  4. bzoj 4871: [Shoi2017]摧毁“树状图”【树形dp】

    做不来--参考https://www.cnblogs.com/ezyzy/p/6784872.html #include<iostream> #include<cstdio> ...

  5. bzoj4871 [Heoi2017]摧毁“树状图”

    刷完了去年的省选题,发现自己dp已经凉凉了. 虽然暴力可以拿到80分的好成绩,但是正解的dp状态和转移还是没能想到,是时候补一波dp了 这道题我们肯定是要树形dp,存的肯定就是子树某种状态的最多的联通 ...

  6. P3748 [六省联考2017]摧毁“树状图”

    传送门 显然是可以树形 $dp$ 的 对每个节点维护以下 $5$ 个东西 $1.$ 从当前节点出发往下的链的最大贡献 $2.$ 节点子树内不经过本身的路径最大贡献 $3.$ 节点子树内经过本身的路径的 ...

  7. SqlServer-无限递归树状图结构设计和查询

    在现实生活中,公司的部门设计会涉及到很多子部门,然后子部门下面又存在子部门,形成类似判断的树状结构,比如说评论楼中楼的评论树状图,职位管理的树状图结构等等,实现类似的树状图数据结构是在开发中经常出现的 ...

  8. Android开源图表之树状图和饼状图的官方示例的整理

    最近由于工作需要,所以就在github上搜了下关于chart的三方框架 官方地址https://github.com/PhilJay/MPAndroidChart 由于工作需要我这里整理了一份Ecli ...

  9. D3树状图给指定特性的边特别显示颜色

    D3作为前端图形显示的利器,功能之强,对底层技术细节要求相对比较多. 有一点,就是要理解其基本的数据和节点的匹配规则架构,即enter,update和exit原理,我前面的D3基础篇中有介绍过,不明白 ...

  10. D3树状图异步按需加载数据

    D3.js这个绘图工具,功能强大不必多说,完全一个Data Driven Document的绘图工具,用户可以按照自己的数据以及希望实现的图形,随心所欲的绘图. 图形绘制,D3默认采用的是异步加载,但 ...

随机推荐

  1. docker 打包镜像过程

    1.首先准备需要打成镜像的JAR包 2.编制Dockerfile文件 FROM docker.gf.com.cn/java:openjdk-8u292-arm64 MAINTAINER 8627905 ...

  2. C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  3. openEuler欧拉安装Jenkins并修改构建workspace路径

    ​一.系统优化 关闭防火墙 systemctl stop firewalld systemctl disable firewalld 关闭selinux sed -ri 's/SELINUX=enfo ...

  4. 02C++顺序结构(1)

    1.C++程序的样子 2.流 输出流 COUT<< 3.一个实例及解析 4.小结 头文件的解释 头文件是C++程序对其他程序的引用,就是让编译器的预处理器把这个输入输出流的标准文件iost ...

  5. 腾讯云 TStor 私有云存储获统信+海光/兆芯官方认证

    腾讯云 TStor 是一款分布式存储产品,致力于解决私有云.混合云下的各类存储需求.产品紧跟国内信创生态,持续加强自主可控能力.目前,TStor 已经支持国内主流国产操作系统和硬件,如中标麒麟操作系统 ...

  6. 6.MySQL性能优化

    参数 作用范围 全局:对实例的所有会话起作用 会话级:只对当前会话起作用 set session binlog_rows_query_log_events = on; set global binlo ...

  7. PySAGES结合CUDA SPONGE增强采样

    技术背景 在前面的一篇博客中,我们介绍过PySAGES这个增强采样软件的基本安装和使用方法.该软件类似于Plumed是一个外挂增强采样软件,但是PySAGES是基于Python语言和Jax框架来实现的 ...

  8. 【Python】【MySQL】Python将JSON数据以文本形式存放到MySQL的Text类型字段中

    1.起因 在做一个自动打卡的玩意.登录会得到那个平台一系列的信息.我又不想专门修改.增加数据库字段来存放,所有打算直接将返回的JSON数据保存到一个MySQL字段中. 内容肯定不能直接放,考虑下比如数 ...

  9. 常用bat代码

    清除空文件夹 | 清理空文件夹 | 删除空文件夹 @echo off for /f "tokens=*" %%i in ('dir/s/b/ad^|sort /r') do rd ...

  10. Windows10 Linux子系统安装图形化界面的两种方法及其对比

    理论上讲,所有Win10的Linux子系统都可以通过Windows10本机远程桌面和Xming的方法来安装使用图形化界面,笔者目前只接触了Debian系的Linux系统,故以Debian GNU/Li ...