设f[i][0/1/2/3/4/5]表示i子树中选一条链不包含根/i子树中选一条链包含根但不能继续向上延伸/i子树中选一条链可以继续向上延伸/选两条链不包含根/选两条链包含根但不能继续向上延伸/选两条链能继续向上延伸,大力讨论即可。代码看起来很(mo)有(ming)意(qi)思(miao)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,p[N],f[N][],t;
int mx[][];
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
inline void up(int &x,int y){x=max(x,y);}
inline int max(int x,int y,int z){return max(max(x,y),z);}
void update(int x)
{
for (int i=;i<;i++)
for (int j=;j<;j++)
if (f[x][i]>f[mx[j][i]][i])
{
for (int k=;k>j;k--) mx[k][i]=mx[k-][i];
mx[j][i]=x;break;
}
}
int findmx(int x){return f[mx[][x]][x];}
int findmx(int x,int y)
{
if (mx[][x]!=mx[][y]) return f[mx[][x]][x]+f[mx[][y]][y];
return max(f[mx[][x]][x]+f[mx[][y]][y],f[mx[][x]][x]+f[mx[][y]][y]);
}
int findmx(int x,int y,int z)
{
int s=-n;
for (int i=;i<;i++)
for (int j=i+;j<;j++)
for (int k=;k<;k++)
if (mx[k][z]!=mx[i][x]&&mx[k][z]!=mx[j][y]) up(s,f[mx[k][z]][z]+f[mx[i][x]][x]+f[mx[j][y]][y]);
return s;
}
int findmx(int a,int b,int c,int d){return f[mx[][a]][a]+f[mx[][b]][b]+f[mx[][c]][c]+f[mx[][d]][d];}
void dfs(int k,int from)
{
int son=;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from) son++,dfs(edge[i].to,k);
memset(mx,,sizeof(mx));
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from) update(edge[i].to);
f[k][]=max(findmx(),findmx()+,findmx()+);
f[k][]=findmx(,)+son-;
f[k][]=max(son,findmx()+son-);
f[k][]=max(findmx(),findmx()+,findmx()+);
for (int i=;i<;i++)
for (int j=i;j<;j++)
up(f[k][],findmx(i,j)+-(i==)-(j==));
f[k][]=max(findmx(,,,)-,max(findmx(,,)-,findmx(,,)-),findmx(,)-)+son;
f[k][]=max(max(findmx()-,findmx(,,)-,max(findmx(,),findmx(,),findmx(,))-),max(findmx(),findmx(),findmx())-)+son;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4871.in","r",stdin);
freopen("bzoj4871.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();int op=read();
while (T--)
{
n=read();if (op>=) read(),read();if (op==) read(),read();
t=;for (int i=;i<=n;i++) p[i]=;
f[][]=f[][]=f[][]=f[][]=f[][]=f[][]=-n;
for (int i=;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
dfs(,);
printf("%d\n",max(max(f[][],f[][],f[][]),max(f[][],f[][],f[][])));
}
return ;
}

BZOJ4871 Shoi2017摧毁“树状图”(树形dp)的更多相关文章

  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 [Heoi2017]摧毁“树状图”

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

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

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

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

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

  6. Android一个炫酷的树状图组织架构图开源控件实现过程

    Android一个炫酷的树状图组织架构图开源控件 文章目录 [1 简介] [2 效果展示] [3 使用步骤] [4 实现基本布局流程] [5 实现自由放缩及拖动] [6 实现添加删除及节点动画] [7 ...

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

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

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

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

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

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

随机推荐

  1. 北京Uber优步司机奖励政策(1月23日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. 《C++ Primer》第II部分:C++标准库

    <C++ Primer>第II部分:C++标准库 前言 把<C++ Primer>读薄系列笔记.本篇为第II部分C++标准库,包含全书第8-12章重难点: IO库 顺序容器 范 ...

  3. CakePHP Model中( 获取Session)使用Component的方法

    有时候我们需要在Model中使用Session,大家知道CakePHP把操作Session的方法封装为了一个Component, 在Model中正常读取Session的方法: 在 "app_ ...

  4. php安全性问题

    目录 常见攻击类型 1.sql注入: 2.xss攻击 3.csrf攻击: php安全三板斧:过滤输入.验证数据,以及转义输出. 1.数据过滤: 2.验证数据: 3.转义输出: laravel 中如何避 ...

  5. vim 打造IDE

    1.MinBufExplorer 2.Ctags Ctags工具是用来遍历源代码文件生成tags文件,这些tags文件能被编辑器或其它工具用来快速查找定位源代码中的符号(tag/symbol),如变量 ...

  6. Android 模拟器 下载、编译及调试

    Android 模拟器源码下载 Android 模拟器源码的下载与 Android AOSP 源码库的下载过程类似,可以参考 Google 官方提供的 Android 源码下载文档 来了解这个过程. ...

  7. JS中String对象常用的方法

    1.  stringObject.charAt(index) 参数:index 必需,即字符在字符串中的下标.  返回值:   返回在指定位置的字符.返回的字符是长度为 1的字符串.(length属性 ...

  8. git 操作几个命令

     git clone ssh://lijianfeng@192.168.1.246:29418/GMGameSDK压栈:git stash查状态:git status切换到要修改的提交:git reb ...

  9. cf#516A. Make a triangle!(三角形)

    http://codeforces.com/contest/1064/problem/A 题意:给出三角形的三条边,问要让他组成三角形需要增加多少长度 题解:规律:如果给出的三条边不能组成三角形,那答 ...

  10. OSG的组成结构

    OSG的组成结构 核心结构 OSG的功能类采用“命名空间+类名称”的形式来命名.命名空间的命名方式为:第一个单词小写,后继单词的首字母大写,例如osg.osgUtil.osgViewer等:类的名称则 ...