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 ...
随机推荐
- Android学习——MediaProvider与Music模块
一.MediaProvider数据库介绍 1. 关系型数据库 关系模型的物理表示是一个二维表格,由行和列组成. 2. MediaProvider数据库存储位置 /data/data/com.a ...
- git上传超过100m大文件
1.git出错如下错误时 执行如下可解决错误: git rm --cache '大文件路径' git commit --amend -CHEAD git push 2.当必须上传大文件时.需借助git ...
- dubbo备忘
http://start.dubbo.io/ https://github.com/dubbo/dubbo-samples https://www.aliyun.com/product/edas ht ...
- html5验证自适应
// 移动端跳转 var OS = function() { var a = navigator.userAgent, b = /(?:Android)/.test(a), d = /(?:Firef ...
- JVM | JVM的核心技术
说到JVM,很多工作多年的老铁,可能就有点发憷了,因为搬砖多年,一直使用java这个工具,对于JVM没有了解过,有句话面试造航母,上班拧螺丝,要啥自行车啊,知道如何搬砖就可以了,为啥要懂这么多,如果你 ...
- 动态库(.so)隐藏函数名
一.偶遇 error: undefined reference to xxx 问题 尝试封装通用的接口到一个private.so,然后供客户端使用,private.so编译出来后由sample.cp ...
- AngularJS 指令(Directivce )一
指令(Directive),是AngularJS中一块比较重要的内容,在实践中,我们提倡将控制器(Controller)写得短小精悍,逻辑代码尽量少,要实现这种目的,我们主要通过将逻辑代码抽取到服务( ...
- maven创建分model的工程
创建parentmvn archetype:generate -DgroupId=com.hikvision -DartifactId=aocp-parent -DarchetypeArtifactI ...
- 手写web框架之开发一个类加载器
ackage io.renren.common; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUti ...
- php进程创建慢导致的502
转自: 作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除地址:http://www.jackxiang.com/post/926 ...