P3748 [六省联考2017]摧毁“树状图”
显然是可以树形 $dp$ 的
对每个节点维护以下 $5$ 个东西

$1.$ 从当前节点出发往下的链的最大贡献
$2.$ 节点子树内不经过本身的路径最大贡献
$3.$ 节点子树内经过本身的路径的最大贡献
$4.$ 从当前节点出发的一条链加上经过这条链的路径构成的图形的最大贡献
$5.$ 从当前节点出发的一条链加上不经过这条链的路径构成的图形的最大贡献
然后就可以大力讨论转移,算答案的时候也同样大力讨论,细节过多,过于恶心
注意上面那些东西的贡献都只考虑在子树内,如果当前节点不是根那么对答案的贡献还要考虑父亲的那一个联通块
代码里面的转移方程有注释(这个题真是丧心病狂)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=5e5+;
int T,G,n;
vector <int> V[N];
int f[N][],Ans;
inline void Max(int &x,int y) { if(y>x) x=y; }
void dfs(int x,int fa)
{
int fg= (!fa) ? : ,sz=V[x].size();
//fg 判断是否有父亲
int fr,sc,ti,fu,vfr,vsc,Lfr,Lsc,mx;
//分别是:最长链,次长链,次次长链,次次次长链,最长链从哪个儿子贡献来的,次长链从哪个儿子贡献来的
//之前所有儿子贡献的最长路径,次长路径,之前儿子内部路径的最大贡献
//为了方便区分,链就是指从x本身出发的一条路径,路径是指不一定从x出发的路径,并且这里的"长"指的是贡献大
fr=sc=ti=fu=vfr=vsc=Lfr=Lsc=mx=;
for(int i=;i<sz;i++)
{
int &v=V[x][i]; if(v==fa) continue;
dfs(v,x);
Max(f[x][], f[v][] + sz- - fg ); // 从儿子v贡献的链,sz-1是因为v本身的联通块没有贡献,-fg是不考虑父亲的贡献
Max(f[x][], max(f[v][],f[v][]) ); // 意义显然
Max(f[x][], f[v][] + sz- - fg ); // 从儿子图形的尾巴延长一个节点
Max(f[x][], f[v][] + sz- - fg ); // 从儿子图形的链往上延长一个节点
Max(f[x][], f[v][] + sz - fg ); // 从不经过儿子的路径加上x本身一个节点作为链,sz不用减1因为儿子的联通块有贡献
Max(f[x][], f[v][] + fr + sz- - fg ); // 从不经过当前儿子的路径加上之前儿子的链延长一个节点
Max(f[x][], f[v][] + sz- - fg ); // 这一行和下一行 与 上一行和上上一行差不多意思,只是路径经过了当前儿子
Max(f[x][], f[v][] + fr + sz- - fg );
Max(f[x][], f[v][] + mx + sz- - fg ); // 最后别忘了当前儿子的链加上之前儿子路径的最大贡献
if(f[v][]>=fr)
{
fu=ti, ti=sc, sc=fr, fr=f[v][];
vsc=vfr, vfr=v;
}
else if(f[v][]>=sc)
fu=ti, ti=sc, sc=f[v][], vsc=v;
else if(f[v][]>=ti) fu=ti,ti=f[v][];
else Max(fu,f[v][]);
//以上维护前4的链
int tmp=max(f[v][],f[v][]);
if(tmp>=Lfr) Lsc=Lfr,Lfr=tmp;
else Max(Lsc,tmp);
//以上维护前2的路径
Max(mx, max(f[v][],f[v][]-) );//维护mx,注意f[v][2]要减1,因为此时v本身没有贡献
}
Max(f[x][],sz-fg); /*本身一个节点作为链*/ f[x][]=f[x][]; // 显然 f[x][2] 包括 f[x][0] 的情况
Max(f[x][], fr + sc + sz- - fg ); // 当然也可以是最长链+次长链的贡献,sz-2是因为贡献最长链和次长链的儿子没有贡献联通块数量
Max(f[x][], max(f[x][],f[x][]) ); // 显然 f[x][3] 包括 f[x][0] 和 f[x][2] 的情况
Max(f[x][], fr + sc + ti + sz- - fg ); // 当前也可以是前 3 名的链的贡献
Max(Ans, Lfr + Lsc + ); // 答案可以是不相交的两条路径
Max(Ans,f[x][] + fg); Max(Ans, max(f[x][],f[x][]) + fg ); // 也要考虑 0,2,3 图形的贡献,记得+fg
Max(Ans, fr + sc + ti + fu + sz- ); // 还可以是前 4 名的链的贡献
for(int i=;i<sz;i++)
{
int &v=V[x][i],one,two;//one是不经过当前儿子的最长链,two的不经过当前儿子的最长路径
if(v==fa) continue;
if(v==vfr) one=sc,two=sc+ti;
else if(v==vsc) one=fr,two=fr+ti;
else one=fr,two=fr+sc;
Max(Ans, f[v][] + sz ); // Ans可以是儿子的路径加上 x 本身看成一条链
Max(Ans, f[v][] + one + sz- ); // 可以是儿子子树内不经过v的路径加上 x 往下的一条链
Max(Ans, f[v][] + two + sz- ); // 可以是儿子子树内不经过v路径加上经过 x 并且不经过当前儿子的路径
Max(Ans, f[v][] + one + sz- ); // 同样要考虑儿子子树内经过 v 的路径加上一些东西
Max(Ans, f[v][] + two + sz- );
Max(Ans, f[v][] + sz- ); // 也可以是儿子的 3 图形往上加上 x 本身构成的图形的贡献
Max(Ans, f[v][] + one + sz- ); // 也可以是儿子的 3 图形往上加上 x 往其他儿子的链构成的图形的贡献
Max(Ans, f[v][] + sz- ); // 也可以是儿子的 4 图形往上加上 x 本身构成的图形的贡献
Max(Ans, f[v][] + one + sz- ); // 也可以是儿子的 4 图形往上加上 x 往其他儿子的链构成的图形的贡献
}
}
inline void Clear()
{
Ans=;
for(int i=;i<=n;i++)
memset(f[i],,sizeof(f[i])),V[i].clear();
}
inline void solve()
{
n=read();
for(int i=;i<=G;i++) int a=read();
for(int i=;i<n;i++)
{
int a=read(),b=read();
V[a].push_back(b); V[b].push_back(a);
}
if(n==) printf("0\n");
else dfs(,),printf("%d\n",Ans);
}
int main()
{
T=read(); G=read()<<;
while(T--) solve(),Clear();
return ;
}
P3748 [六省联考2017]摧毁“树状图”的更多相关文章
- 六省联考2017 Day1
目录 2018.3.18 Test T1 BZOJ.4868.[六省联考2017]期末考试 T2 T3 BZOJ.4870.[六省联考2017]组合数问题(DP 矩阵快速幂) 总结 考试代码 T1 T ...
- 洛谷 P3747 [六省联考2017]相逢是问候 解题报告
P3747 [六省联考2017]相逢是问候 题目描述 \(\text {Informatik verbindet dich und mich.}\) 信息将你我连结. \(B\) 君希望以维护一个长度 ...
- 【BZOJ4873】[六省联考2017]寿司餐厅(网络流)
[BZOJ4873][六省联考2017]寿司餐厅(网络流) 题面 BZOJ 洛谷 题解 很有意思的题目 首先看到答案的计算方法,就很明显的感觉到是一个最大权闭合子图. 然后只需要考虑怎么构图就行了. ...
- 【BZOJ4868】[六省联考2017]期末考试(贪心)
[BZOJ4868][六省联考2017]期末考试(贪心) 题面 BZOJ 洛谷 题解 显然最终的答案之和最后一个公布成绩的课程相关. 枚举最后一天的日期,那么维护一下前面有多少天可以向后移,后面总共需 ...
- 六省联考2017 Day2
目录 2018.3.27 Test 总结 T1 T2 T3 BZOJ.4873.[六省联考2017]寿司餐厅(最小割ISAP 最大权闭合子图) 考试代码 T1 T2 T3 2018.3.27 Test ...
- P3746 [六省联考2017]组合数问题
P3746 [六省联考2017]组合数问题 \(dp_{i,j}\)表示前\(i\)个物品,取的物品模\(k\)等于\(r\),则\(dp_{i,j}=dp_{i-1,(j-1+k)\%k}+dp_{ ...
- [luogu] P3745 [六省联考2017]期末考试 (贪心)
P3745 [六省联考2017]期末考试 题目描述 有 \(n\) 位同学,每位同学都参加了全部的 \(m\) 门课程的期末考试,都在焦急的等待成绩的公布. 第 \(i\) 位同学希望在第 \(t_i ...
- bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]
4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...
- bzoj 4871: [Shoi2017]摧毁“树状图”
4871: [Shoi2017]摧毁“树状图” Time Limit: 25 Sec Memory Limit: 512 MBSubmit: 53 Solved: 9[Submit][Status ...
随机推荐
- 【Eureka】Eureka 是什么
Eureka是什么? Eureka 是 Netflix 的一个子模块,也是核心模块之一.Eureka 是一个基于 Rest 的服务,用于定位服务,以实现云端中间层服务发现和故障转移.服务注册和发现对于 ...
- sql 同一张表查询不同数据合并之后关联查询
SELECT t.articleId articleId, comments.`comments` parentComment, t.commentId commentsId, comments.`i ...
- qt5之网络通信
QT5 TCP网络通讯 服务器与客户端建立连接listen() - connectToHost(); 触发newPendingConnect信号 实时数据通讯write(); read(); 触发 ...
- MySQL 如何使用show processlist进行过滤
在使用show processlist的时候,直接使用会显示很多的内容,无法很快找到需要的信息. 如何过滤操作呢? 其实,show processlist展示的内容是从information_sche ...
- Vue项目打包后背景图片路径错误
vue项目打包之后背景图片出错的解决方案如下: 1,找到 config->index.js里面,如下修改 默认配置: env: require('./prod.env'), index: pat ...
- 科大讯飞sdk语音合成工具类
注:主要是dll文件的配置 A:Java SDK 使用了 JNI 形式,在初始化 SDK 时,SDK 将加载共享库(Windows下为msc32.dll或msc64.dll文件,Linux下libms ...
- 1.ini读写操作
一.使用 TIniFile implementationvar ini:tinifile; path:string; {ini文件路径} section,key:string;{表示 ...
- React Native创建项目等待时间长解决
1. 初始化工程 在终端输入命令 :react-native init AwesomeProject 从命令上看,看起来是初始化一个工程,于是, 1分钟...... 10分钟...... 1小时... ...
- java内存模型的原子性、可见性、有序性与指令重排序
在并发编程中,我们通常会遇到以下三个概念:原子性.可见性和有序性.我们先看具体看一下这三个概念: 1.原子性 操作时不可分割的比如a=0,此操作不可分割,而++a,实际上是a=a+1,为两个操作.想将 ...
- C# 3Des加密解密
第三方的加密规则约定:加密经过3DES加密后的Base64 编码 最近在对接一个第三方接口,请求参数和响应参数全采用3des加密规则,由于我是用.NET对接的,而第三方是Java开发的,所以两种程 ...