题意:给定一棵$n$个点的树,将叶子节点分为数个集合使集合里点对最长距离不超过$k$,求最少集合数。($n\le1000000$)

首先我们可以想到,这道题并不是让你构造最优方案,因为只要把所有叶子节点的集合任意合并至无法操作,就一定是最优答案了

这个感性理解一下就是那么回事,我一开始做的时候就想到的

然后其实我们把叶子结点向上合并即可,只要子树内两个集合的距离不超过$k$,就把他们合起来,记成到当前点距离较大的那个集合

这样对于子树两两合并,我们可以用启发式合并的堆来实现,复杂度是$nlog^2n$,并不足以通过这道题

再想想看,其实如果一个集合和当前最小的集合已经无法合并了,就不用再往上推了,因为上边的集合的最远点只会更远,所以把这个集合留住在这,答案加一

然后我们可以把子树内两个集合的距离不超过$k$的集合合并起来,这样我们每次向上传递的只有一个集合了,复杂度$nlogn$

就从一道大数据结构题变成了一道思维难度更大的题了

代码:

 #include<iostream>
#include<cstdio>
#include<queue>
#define M 1000010
using namespace std;
int read()
{
char ch=getchar();int x=;
while(ch>''||ch<'') ch=getchar();
while(ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x;
}
int n,num,ans,k;
int head[M],in[M];
struct point{int to,next;}e[M<<];
void add(int from,int to)
{
e[++num].next=head[from];
e[num].to=to;
head[from]=num;
}
int dfs(int x,int fa)
{
if(in[x]==) return ;
priority_queue<int>q;
for(int i=head[x];i;i=e[i].next)
{
int to=e[i].to;
if(to==fa) continue;
q.push(dfs(to,x)+);
}
int maxn=q.top();q.pop();
while(!q.empty())
{
if(q.top()+maxn<=k) return maxn;
ans++;
maxn=q.top();
q.pop();
}
return maxn;
}
int main()
{
n=read(); k=read();
for(int i=;i<n;i++)
{
int a=read(),b=read();
add(a,b); add(b,a);
in[a]++; in[b]++;
}
for(int i=;i<=n;i++) if(in[i]!=){dfs(i,);break;}
printf("%d",ans+);
return ;
}

[CF1042F]Leaf Sets的更多相关文章

  1. cf1042F. Leaf Sets(贪心)

    题意 题目链接 给出一棵树,删除一些边,使得任意联通块内的任意点距离不超过$k$ sol 考场上想的贪心是对的:考虑一棵子树,如果该子树内最深的两个节点的距离相加$>k$就删掉最深的那个点,向上 ...

  2. CF1042F Leaf Sets (贪心+树上构造)

    题目大意:给你一棵树,让你对叶节点分组,保证每组中,任意两个叶节点之间的距离不大于K,求最小的组数 手动yy的贪心竟然对的 对于每个节点,维护一个$ma[i]$,表示在$i$节点的子树内 未被分组的叶 ...

  3. 【CF1042F】Leaf Sets

    [CF1042F]Leaf Sets 题面 洛谷 题解 对于一个根节点\(x\),考虑其子树内的所有\(lca\)为它的叶子节点到它的距离\(d_1<d2<...<d_m\). 那么 ...

  4. CF 1042 F. Leaf Sets

    F. Leaf Sets http://codeforces.com/contest/1042/problem/F 题意: 将所有的叶子节点分配到尽量少的集合,一个可行的集合中两两叶子节点的距离< ...

  5. CodeForces 1042 F Leaf Sets 贪心

    Leaf Sets 题意:给你一棵树,树上有n个点,只有一条边的点叫做叶子,现在要求把所有的叶子分组,每个组内的所有叶子的距离都不能大于k. 题解: 我们可以随意找一个不是叶子的节点当做这颗树的根节点 ...

  6. 「CF1042F」Leaf Sets

    传送门 Luogu 解题思路 比较显然的一种做法: 我们把一个点的子树高度抠出来并排序记为 \(L_i\),找到最大的 \(i\) 使得 \(L_{i-1}+L_i\le K\). 于是我们把前 \( ...

  7. Leaf Sets CodeForces - 1042F (树,最小划分)

    大意: 给定树, 求叶子的最小划分, 使得每个划分内任意两个叶子距离不超过k. 任选一个非叶结点, 贪心合并. #include <iostream> #include <sstre ...

  8. [CF]Round510

    由于我的codeforces的帐号登不上,所以我错过了这场比赛,只好赛后再抄题解自己做. A Benches 最大的情况就是所有人都挤在那个人最多的长椅上,最小的情况是所有人尽量平均的坐. #incl ...

  9. TOJ 4008 The Leaf Eaters(容斥定理)

    Description As we all know caterpillars love to eat leaves. Usually, a caterpillar sits on leaf, eat ...

随机推荐

  1. maven POM —— maven权威指南学习笔记(五)

    1. 简介 Archetype插件通过 pom.xml 文件创建了一个项目.这就是项目对象模型 (POM),一个项目的声明性描述. 当Maven运行一个目标的时候,每个目标都会访问定 义在项目POM里 ...

  2. Yii框架2.0的过滤器

    过滤器是 控制器 动作 执行之前或之后执行的对象. 例如访问控制过滤器可在动作执行之前来控制特殊终端用户是否有权限执行动作, 内容压缩过滤器可在动作执行之后发给终端用户之前压缩响应内容. 过滤器可包含 ...

  3. UDP和TCP的主要特点

    UDP的主要特点是:(1)无连接:(2)尽最大努力交付:(3)面向报文:(4)无拥塞控制:(5)支持一对一.一对多.多对一和多对多的交互通信:(6)首部开销小(只有四个字段:源端口.目的端口.长度.检 ...

  4. 年假小 Plan

    Learn 董伟明 课程 https://www.pycourses.com/ Learn 500 Lines or Less https://github.com/HT524/500LineorLe ...

  5. apt-get tips

    1.通过apt-get安装指定版本的软件 apt-get install <package name>=<version> 2.通过apt-cache列举所有可获取的版本 ap ...

  6. 【我的Android进阶之旅】Android目录过长造成错误:Failed to crunch file abc_textfield_search_activated_mtrl_alpha.9.png

    一.编译异常描述 一大早来开发一个新的需求,拉取了一个新的分支,然后导入Android Studio之后,编译就报错了,报错如下所示: 错误具体日志如下所示: Information:Gradle t ...

  7. 赵雅智_ListView_ArrayAdapter

    ArrayAdapter六种构造方法的作用 ArrayAdapter<T>(Context context, int textViewResourceId); 上下文,布局文件 Array ...

  8. 关于Windows Service的一个编写技巧

    写过Windows Service的朋友都知道服务是不可以直接在vs里面启动调试,我们必须修改Program.cs文件来达到我们调试的目的,等服务调试好了以后还要把代码改回来,显非常的不方便,在这里为 ...

  9. C++实现去掉string字符串前后的空白字符

    C++标准库提供的字符串类string没有提供类似CString中Trim方法,该方法功能为去除字符串前后的空白字符.利用string自身一些方法可以很容易实现该功能. 如下: void Trim(s ...

  10. 漫谈DOM 事件流的三个阶段

    一丶 流 什么是流? 比如 react 中的单项数据流,Node.js 中的流,或者本文中的 DOM 事件流,都是流的具体体现.专业地讲,流是程序输入或输出的一个连续的字节序列:通俗地讲,流是有方向的 ...