2018.09.01 独立集(树形dp)
描述
给定一颗树(边权为1),选取一个节点子集,使得该集合中任意两个节点之间的距离都大于K。求这个集合节点最多是多少
输入
第一行是两个整数N,K
接下来是N-1行,每行2个整数x,y,表示x与y有一条边
输出
1个整数表示最多的节点数
样例输入
3 1
1 2
1 3
样例输出
2
提示
| 测试点 | N的上限 | K | 特征 |
|---|---|---|---|
| 1 | 15 | 1 | |
| 2 | 1000 | 1 | 链 |
| 3 | 1000 | 1 | |
| 4 | 100000 | 1 | 链 |
| 5 | 100000 | 1 | |
| 6 | 15 | 2 | |
| 7 | 1000 | 2 | 链 |
| 8 | 1000 | 2 | |
| 9 | 100000 | 2 | 链 |
| 10 | 100000 | 2 |
树形dp入门题。
T=2的情况有点意思。
设当前访问第i个节点。
f[i][0]" role="presentation" style="position: relative;">f[i][0]f[i][0]:i不选但i父亲选。
f[i][1]" role="presentation" style="position: relative;">f[i][1]f[i][1]:不选且i父亲不选。
f[i][2]" role="presentation" style="position: relative;">f[i][2]f[i][2]:i选。
显然有:
f[i][2]=1+∑vf[v][0]" role="presentation" style="position: relative;">f[i][2]=1+∑vf[v][0]f[i][2]=1+∑vf[v][0]
以及:
f[i][0]=∑vf[v][1]" role="presentation" style="position: relative;">f[i][0]=∑vf[v][1]f[i][0]=∑vf[v][1]
关键是f[i][1]" role="presentation" style="position: relative;">f[i][1]f[i][1]
这个东西需要考虑儿子之间是否冲突,因此最优值的产生有两种可能:
1. 所有儿子都不选。
2. 某一个儿子选,其余不选。
因此有f[i][1]=(∑vf[v][1])+max(0,f[v][2]−f[v][1])" role="presentation" style="position: relative;">f[i][1]=(∑vf[v][1])+max(0,f[v][2]−f[v][1])f[i][1]=(∑vf[v][1])+max(0,f[v][2]−f[v][1])。
代码:
#include<bits/stdc++.h>
#define N 100005
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int first[N],n,k,cnt=0,f[N][3];
struct edge{int v,next;}e[N<<1];
inline void add(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;}
inline int max(int a,int b){return a>b?a:b;}
inline int dfs1(int p,bool k,int fa){
if(f[p][k]!=-1)return f[p][k];
f[p][k]=k;
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
if(!k)f[p][k]+=max(dfs1(v,0,p),dfs1(v,1,p));
else f[p][k]+=dfs1(v,0,p);
}
return f[p][k];
}
inline int dfs2(int p,int k,int fa){
if(f[p][k]!=-1)return f[p][k];
f[p][k]=(k==2);
if(!k){
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
f[p][k]+=dfs2(v,1,p);
}
}
else if(k==1){
int max1=0;
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
f[p][k]+=dfs2(v,1,p);
int tmp=dfs2(v,2,p)-dfs2(v,1,p);
if(max1<tmp)max1=tmp;
}
f[p][k]+=max1;
}
else for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
f[p][k]+=dfs2(v,0,p);
}
return f[p][k];
}
int main(){
n=read(),k=read();
for(int i=1;i<n;++i){
int u=read(),v=read();
add(u,v),add(v,u);
}
memset(f,-1,sizeof(f));
if(k==1)cout<<max(dfs1(1,1,1),dfs1(1,0,1));
else cout<<max(dfs2(1,1,1),dfs2(1,2,1));
return 0;
}
2018.09.01 独立集(树形dp)的更多相关文章
- 2018.09.01 loj#2330. 「清华集训 2017」榕树之心(树形dp)
传送门 树形dp好题啊. 我们用w[i]" role="presentation" style="position: relative;">w[ ...
- P4383 [八省联考2018]林克卡特树 树形dp Wqs二分
LINK:林克卡特树 作为树形dp 这道题已经属于不容易的级别了. 套上了Wqs二分 (反而更简单了 大雾 容易想到还是对树进行联通情况的dp 然后最后结果总和为各个联通块内的直径. \(f_{i,j ...
- 2018.09.01 poj3071Football(概率dp+二进制找规律)
传送门 概率dp简单题. 设f[i][j]表示前i轮j获胜的概率. 如果j,k能够刚好在第i轮相遇,找规律可以发现j,k满足: (j−1)>>(i−1)" role=" ...
- 2018.09.01 hdu4405 Aeroplane chess (期望dp)
传送门 期望dp简单题啊. 不过感觉题意不太对. 手过了一遍样例发现如果有捷径必须走. 这样的话就简单了啊. 设f[i]" role="presentation" sty ...
- 2018.09.01 09:22 Exodus
Be careful when writing in the blog garden. Sometimes you accidentally write something wrong, and yo ...
- 2018.09.01 09:08 Genesis
Nothing to think about, I don't know where to start, the mastery of learning is not an easy task, yo ...
- 2018.09.01 poj2689 Prime Distance(埃式筛法)
传送门 一道挺有趣的. 第一眼以为每个数都用miller_rabin判一次,但感觉会被卡时间啊. 继续分析发现可以晒出sqrt(r)中的所有素数,然后用类似埃式筛法的方法晒出[l,r]" r ...
- 2018.09.14 洛谷P3931 SAC E#1 - 一道难题 Tree(树形dp)
传送门 简单dp题. f[i]表示以i为根的子树被割掉的最小值. 那么有: f[i]=min(∑vf[v],dist(i,fa))" role="presentation" ...
- 2018.09.06 警卫安排(树形dp)
描述 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:有边直接相连的宫殿可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全 ...
随机推荐
- J2SE 8的Lambda --- Comparator
Person[] personArray = new Person[]{new Person("Tom"),new Person("Jack"),new Per ...
- Spring MVC 支持的原生API参数
HttpServletRequest HttpServletResponse HttpSession java.security.Principal Local InputStream OutputS ...
- OpenSL ES 查询设备支持的SL Profiles
opensl es 提供了三种类型:分别是 SL_PROFILES_PHONE(手机):SL_PROFILES_MUSIC(音乐); SL_PROFILES_GAME (游戏). 如果你使用的手机的开 ...
- jqGrid 使用案例及笔记
jqGrid 是一个用来显示网格数据的jQuery插件,通过使用jqGrid可以轻松实现前端页面与后台数据的ajax异步通信. 一.要引用的文件 要使用jqGrid,首先页面上要引入如下css与js文 ...
- Java常见的乱码解决方式
JAVA几种常见的编码格式(转) 简介 编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换较多.本文将向你详细介绍 Java 中编码 ...
- PPT汇报 评审表
评审表 团队编号 团队名称 团队项目名称 格式评审 内容评审 PPT评审 演讲评审 优点 存在问题(至少提3点) 建议 01 牛肉面不要牛肉不要面 02 正义联盟 我是一个图书小平台 03 什么队 & ...
- hibernate中.常见的hql查询语句
hql是非常有意识的被设计为完全面向对象的查询 基本规则: 1.hql语法类似于sql,但它后面跟的不是表名和字段名,而是类名和属性名 2.hql大小写不敏感.但是设计java类名,包名,属性名时大小 ...
- localstorage是什么,它有哪些作用
localStorage作为HTML5本地存储web storage特性的API之一,主要作用是将数据保存在客户端中,而客户端一般是指上海网站设计用户的计算机.在移动设备上,由于大部分浏览器都支持 w ...
- 这两天的刷机+Root
最近为了研究Xposed框架的搭建使用,将自己红米Note2尝试root后,开不了机了.后使用(网上下载的线刷宝,刷的官网线刷宝成功开机了,然后里面会自带很多软件,然后通过下载KingRoot将手机自 ...
- 参数错误导致bug
1.网站参数与数据库参数名字不一致(大小写). 2.参数漏掉一个字母(characterno写成了charaterno).