[CF1042F]Leaf Sets
题意:给定一棵$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的更多相关文章
- cf1042F. Leaf Sets(贪心)
题意 题目链接 给出一棵树,删除一些边,使得任意联通块内的任意点距离不超过$k$ sol 考场上想的贪心是对的:考虑一棵子树,如果该子树内最深的两个节点的距离相加$>k$就删掉最深的那个点,向上 ...
- CF1042F Leaf Sets (贪心+树上构造)
题目大意:给你一棵树,让你对叶节点分组,保证每组中,任意两个叶节点之间的距离不大于K,求最小的组数 手动yy的贪心竟然对的 对于每个节点,维护一个$ma[i]$,表示在$i$节点的子树内 未被分组的叶 ...
- 【CF1042F】Leaf Sets
[CF1042F]Leaf Sets 题面 洛谷 题解 对于一个根节点\(x\),考虑其子树内的所有\(lca\)为它的叶子节点到它的距离\(d_1<d2<...<d_m\). 那么 ...
- CF 1042 F. Leaf Sets
F. Leaf Sets http://codeforces.com/contest/1042/problem/F 题意: 将所有的叶子节点分配到尽量少的集合,一个可行的集合中两两叶子节点的距离< ...
- CodeForces 1042 F Leaf Sets 贪心
Leaf Sets 题意:给你一棵树,树上有n个点,只有一条边的点叫做叶子,现在要求把所有的叶子分组,每个组内的所有叶子的距离都不能大于k. 题解: 我们可以随意找一个不是叶子的节点当做这颗树的根节点 ...
- 「CF1042F」Leaf Sets
传送门 Luogu 解题思路 比较显然的一种做法: 我们把一个点的子树高度抠出来并排序记为 \(L_i\),找到最大的 \(i\) 使得 \(L_{i-1}+L_i\le K\). 于是我们把前 \( ...
- Leaf Sets CodeForces - 1042F (树,最小划分)
大意: 给定树, 求叶子的最小划分, 使得每个划分内任意两个叶子距离不超过k. 任选一个非叶结点, 贪心合并. #include <iostream> #include <sstre ...
- [CF]Round510
由于我的codeforces的帐号登不上,所以我错过了这场比赛,只好赛后再抄题解自己做. A Benches 最大的情况就是所有人都挤在那个人最多的长椅上,最小的情况是所有人尽量平均的坐. #incl ...
- TOJ 4008 The Leaf Eaters(容斥定理)
Description As we all know caterpillars love to eat leaves. Usually, a caterpillar sits on leaf, eat ...
随机推荐
- CodeForces 731A Night at the Museum
A. Night at the Museum time limit per test 1 second memory limit per test 256 megabytes input standa ...
- NSUserDefault 保存自定义对象
由于NSUserDefaults 不支持保存自定类,保存的对象需要实现NSCoding协议,不过自定的类型就算实现了NSCoding也不可以保存,可以通过以下方法实现: //h文件 #import & ...
- glibc-2.23_int_malloc_流程浅析
- Python进阶知识
装饰器 迭代器 生成器 mixins 元编程 描述符 量化领域常用 列表推导式 字典推导式 高阶函数 lambda函数 三目表达式
- Favorite Donut--hdu5442(2015年长春网选赛,kmp,最大表示法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5442 打比赛的时候还没学kmp更没有学最大最小表示法,之后做完了kmp的专题,学了它们,现在再来做这道 ...
- 解决iOS xcode打包unknown error -1=ffffffffffffffff错误
# 网上很多文档说重启机器,清除缓存什么的,纯属扯淡,都是相互复制粘贴,经测验在stackoverflow找到以下解决方法,亲测可用security unlock-keychain -p " ...
- Linux Anaconda安装步骤
首选下载wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh 可以去官网查看适合自己的文件https://www ...
- C++入门(2)
第一个程序,输入输出: #include <iostream> using namespace std; int main() { cout << "Hello, w ...
- 360UI 界面框架 即QUI框架与EXT比较
EXTJS框架是非常全面和成熟的,这是因为它发展的年头久远,并且有全世界的EXTJS爱好者为其出谋献策,它的组件库尤其是DataGrid组件无人能出其右.我在最初也考虑过使用EXTJS来做项目,学习了 ...
- Java-小技巧-004-jdk时间,jdk8时间,joda,calendar,获取当前时间前一周、前一月、前一年的时间
1.推荐使用java8 localdate等 线程安全 支持较好 地址 2.joda 一.简述 查看SampleDateFormat源码,叙述有: * Date formats are not syn ...