描述

给定一颗树(边权为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)的更多相关文章

  1. 2018.09.01 loj#2330. 「清华集训 2017」榕树之心(树形dp)

    传送门 树形dp好题啊. 我们用w[i]" role="presentation" style="position: relative;">w[ ...

  2. P4383 [八省联考2018]林克卡特树 树形dp Wqs二分

    LINK:林克卡特树 作为树形dp 这道题已经属于不容易的级别了. 套上了Wqs二分 (反而更简单了 大雾 容易想到还是对树进行联通情况的dp 然后最后结果总和为各个联通块内的直径. \(f_{i,j ...

  3. 2018.09.01 poj3071Football(概率dp+二进制找规律)

    传送门 概率dp简单题. 设f[i][j]表示前i轮j获胜的概率. 如果j,k能够刚好在第i轮相遇,找规律可以发现j,k满足: (j−1)>>(i−1)" role=" ...

  4. 2018.09.01 hdu4405 Aeroplane chess (期望dp)

    传送门 期望dp简单题啊. 不过感觉题意不太对. 手过了一遍样例发现如果有捷径必须走. 这样的话就简单了啊. 设f[i]" role="presentation" sty ...

  5. 2018.09.01 09:22 Exodus

    Be careful when writing in the blog garden. Sometimes you accidentally write something wrong, and yo ...

  6. 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 ...

  7. 2018.09.01 poj2689 Prime Distance(埃式筛法)

    传送门 一道挺有趣的. 第一眼以为每个数都用miller_rabin判一次,但感觉会被卡时间啊. 继续分析发现可以晒出sqrt(r)中的所有素数,然后用类似埃式筛法的方法晒出[l,r]" r ...

  8. 2018.09.14 洛谷P3931 SAC E#1 - 一道难题 Tree(树形dp)

    传送门 简单dp题. f[i]表示以i为根的子树被割掉的最小值. 那么有: f[i]=min(∑vf[v],dist(i,fa))" role="presentation" ...

  9. 2018.09.06 警卫安排(树形dp)

    描述 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:有边直接相连的宫殿可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全 ...

随机推荐

  1. J2SE 8的Lambda --- Comparator

    Person[] personArray = new Person[]{new Person("Tom"),new Person("Jack"),new Per ...

  2. Spring MVC 支持的原生API参数

    HttpServletRequest HttpServletResponse HttpSession java.security.Principal Local InputStream OutputS ...

  3. OpenSL ES 查询设备支持的SL Profiles

    opensl es 提供了三种类型:分别是 SL_PROFILES_PHONE(手机):SL_PROFILES_MUSIC(音乐); SL_PROFILES_GAME (游戏). 如果你使用的手机的开 ...

  4. jqGrid 使用案例及笔记

    jqGrid 是一个用来显示网格数据的jQuery插件,通过使用jqGrid可以轻松实现前端页面与后台数据的ajax异步通信. 一.要引用的文件 要使用jqGrid,首先页面上要引入如下css与js文 ...

  5. Java常见的乱码解决方式

    JAVA几种常见的编码格式(转)   简介 编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换较多.本文将向你详细介绍 Java 中编码 ...

  6. PPT汇报 评审表

    评审表 团队编号 团队名称 团队项目名称 格式评审 内容评审 PPT评审 演讲评审 优点 存在问题(至少提3点) 建议 01 牛肉面不要牛肉不要面 02 正义联盟 我是一个图书小平台 03 什么队 & ...

  7. hibernate中.常见的hql查询语句

    hql是非常有意识的被设计为完全面向对象的查询 基本规则: 1.hql语法类似于sql,但它后面跟的不是表名和字段名,而是类名和属性名 2.hql大小写不敏感.但是设计java类名,包名,属性名时大小 ...

  8. localstorage是什么,它有哪些作用

    localStorage作为HTML5本地存储web storage特性的API之一,主要作用是将数据保存在客户端中,而客户端一般是指上海网站设计用户的计算机.在移动设备上,由于大部分浏览器都支持 w ...

  9. 这两天的刷机+Root

    最近为了研究Xposed框架的搭建使用,将自己红米Note2尝试root后,开不了机了.后使用(网上下载的线刷宝,刷的官网线刷宝成功开机了,然后里面会自带很多软件,然后通过下载KingRoot将手机自 ...

  10. 参数错误导致bug

    1.网站参数与数据库参数名字不一致(大小写). 2.参数漏掉一个字母(characterno写成了charaterno).