bzoj4871 [Heoi2017]摧毁“树状图”
刷完了去年的省选题,发现自己dp已经凉凉了。
虽然暴力可以拿到80分的好成绩,但是正解的dp状态和转移还是没能想到,是时候补一波dp了
这道题我们肯定是要树形dp,存的肯定就是子树某种状态的最多的联通块数,那么我们发现有这么几个因素会影响转移
1.子树的根是否被删掉
2.是否有一条链可以从子树中伸出去,即根连的链数是不是奇数
3.子树中共出现了几条路径
那么f[i][0/1(n点删不删)][0/1(能否向上扩展)][0/1/2(子树中共有几条路径)]就是我们的数组定义
转移时我是直接让新的子树和已有的子树信息进行合并,也需要额外记录两个信息,即当前共有几棵子树和当前子树中只有1条路径时的删去根结点时的信息。
看起来状态定义十分麻烦,但是实际只有6个状态是有用的,手动转移,理解了就比较简单。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define N 100500
using namespace std;
int e=,head[N];
struct edge{
int v,next;
}ed[N<<];
inline void add(int u,int v){
ed[e].v=v;
ed[e].next=head[u];
head[u]=e++;
}
int T,opt,n,ans;
int f[N][][][];//f[i][0/1(n点删不删)][0/1(能否向上扩展)][0/1/2(子树中共有几条路径)]
inline void gmax(int &x,int y){x=x>y?x:y;}
inline int Max(int x,int y){return x>y?x:y;}
void dfs(int x,int fa){
int son=,t=;
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa)continue;
dfs(v,x);
int f1,f2,f3,f4,f5,f6;
f1=f[x][][][];
f2=f[x][][][];
f3=f[x][][][]+;
f4=f[x][][][]+;
f5=f[x][][][]+;
f6=f[x][][][]+;
gmax(f1,f[v][][][]);
gmax(f1,f[v][][][]+);
gmax(f1,f[v][][][]+); gmax(f2,f[v][][][]);
gmax(f2,f[v][][][]+);
gmax(f2,f[v][][][]+);
gmax(f2,f[x][][][]+f[v][][][]-);
gmax(f2,f[x][][][]+f[v][][][]);
gmax(f2,f[x][][][]+f[v][][][]); gmax(f3,f[v][][][]+son);
gmax(f4,f[x][][][]+f[v][][][]); gmax(f5,f[v][][][]+son);
gmax(f5,f[x][][][]+f[v][][][]);
gmax(f5,f[x][][][]+f[v][][][]);
gmax(f5,f[x][][][]+f[v][][][]);
gmax(f5,t+f[v][][][]);
gmax(f5,f[x][][][]+f[v][][][]); gmax(f6,f[x][][][]+f[v][][][]);
gmax(f6,f[x][][][]+f[v][][][]);
gmax(f6,f[x][][][]+f[v][][][]);
gmax(f6,f[x][][][]+f[v][][][]); t=Max(t+,son+Max(f[v][][][],Max(f[v][][][],f[v][][][])));
son++; f[x][][][]=f1;
f[x][][][]=f2;
f[x][][][]=f3;
f[x][][][]=f4;
f[x][][][]=f5;
f[x][][][]=f6;
}
gmax(f[x][][][],son);
}
inline void init(){
e=;
for(int i=;i<=n;++i)
memset(f[i],,sizeof f[i]),head[i]=;
}
inline int read(){
int a=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')a=a*+(ch^),ch=getchar();
return a;
}
int main(){
scanf("%d%d",&T,&opt);
while(T--){
n=read();
init();
for(int i=;i<=opt;++i)read(),read();
for(int i=,u,v;i<n;++i){
u=read();v=read();
add(u,v);add(v,u);
}
dfs(,);
ans=Max(f[][][][],Max(f[][][][],f[][][][]));
printf("%d\n",ans);
}
return ;
}
bzoj4871 [Heoi2017]摧毁“树状图”的更多相关文章
- BZOJ4871 Shoi2017摧毁“树状图”(树形dp)
设f[i][0/1/2/3/4/5]表示i子树中选一条链不包含根/i子树中选一条链包含根但不能继续向上延伸/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 ...
- bzoj 4871: [Shoi2017]摧毁“树状图”【树形dp】
做不来--参考https://www.cnblogs.com/ezyzy/p/6784872.html #include<iostream> #include<cstdio> ...
- P3748 [六省联考2017]摧毁“树状图”
传送门 显然是可以树形 $dp$ 的 对每个节点维护以下 $5$ 个东西 $1.$ 从当前节点出发往下的链的最大贡献 $2.$ 节点子树内不经过本身的路径最大贡献 $3.$ 节点子树内经过本身的路径的 ...
- SqlServer-无限递归树状图结构设计和查询
在现实生活中,公司的部门设计会涉及到很多子部门,然后子部门下面又存在子部门,形成类似判断的树状结构,比如说评论楼中楼的评论树状图,职位管理的树状图结构等等,实现类似的树状图数据结构是在开发中经常出现的 ...
- Android开源图表之树状图和饼状图的官方示例的整理
最近由于工作需要,所以就在github上搜了下关于chart的三方框架 官方地址https://github.com/PhilJay/MPAndroidChart 由于工作需要我这里整理了一份Ecli ...
- D3树状图给指定特性的边特别显示颜色
D3作为前端图形显示的利器,功能之强,对底层技术细节要求相对比较多. 有一点,就是要理解其基本的数据和节点的匹配规则架构,即enter,update和exit原理,我前面的D3基础篇中有介绍过,不明白 ...
- D3树状图异步按需加载数据
D3.js这个绘图工具,功能强大不必多说,完全一个Data Driven Document的绘图工具,用户可以按照自己的数据以及希望实现的图形,随心所欲的绘图. 图形绘制,D3默认采用的是异步加载,但 ...
随机推荐
- app ionic1 微信 微博 分享功能的实现
微信分享 1.登录微信开放平台注册账户 2.创建一个移动应用 (app) 审核过后会有一个appid 之后安装插件的时候会用到 3.在这个应用上面填写 包名 和 签名 就可以了 包名和签名的 ...
- Spring Cloud入门教程-Ribbon实现客户端负载均衡
简介 我们继续以之前博客的代码为基础,增加Ribbon组件来提供客户端负载均衡.负载均衡是实现高并发.高性能.可伸缩服务的重要组成部分,它可以把请求分散到一个集群中不同的服务器中,以减轻每个服务器的负 ...
- mina框架tcpt通讯接收数据断包粘包处理
用mina做基于tcp,udp有通讯有段时间了,一直对编码解码不是很熟悉,这次做项目的时候碰到了断包情况,贴一下解决过程, 我接受数据格式如下图所示: unit32为c++中数据类型,代表4个字节,由 ...
- 判断NaN in JavaScript
[NaN 作用是用来表示一个值不是数字] NaN在JavaScript中行为很怪异,是因为那NaN和任何值都不相等(包括它自己). NaN === NaN; // false因为 ...
- SQL Server性能优化(8)堆表结构介绍
一.表结构综述 下图是SQL Server中表的组织形式(其中分区1.分区2是为了便于管理,把表进行分区,放到不同的硬盘数据文件里.默认情况下,表只有一个分区.).表在硬盘上的存放形式,有堆和B树两种 ...
- 构建具有用户身份认证的 Ionic 应用
序言:本文主要介绍了使用 Ionic 和 Cordova 开发混合应用时如何添加用户身份认证.教程简易,对于 Ionic 入门学习有一定帮助.因为文章是去年发表,所以教程内关于 Okta 的一些使用步 ...
- Java并发之ReentrantReadWriteLock
上篇文章简单的介绍了ReentrantLock可重入锁.事实上我们可以理解可重入锁是一种排他锁,排他锁在同一个时刻只能够由一个线程进行访问.这就与我们实际使用过程中有点不想符合了,比如说当我们进行读写 ...
- Thymeleaf中each标签遍历list如何获取index
<tr th:each="user,userStat:${users}">userStat是状态变量,有 index,count,size,current,even,o ...
- 接口调用(发送http请求)
// 向对应的url地址发送http请求, 并获取响应的json字符串 public String getHttpResponse(String url) { // result用 ...
- oracle批量插入测试数据
做数据库开发或管理的人经常要创建大量的测试数据,动不动就需要上万条,如果一条一条的录入,那会浪费大量的时间,本文介绍了Oracle中如何通过一条 SQL快速生成大量的测试数据的方法.产生测试数据的SQ ...