CF1042F Leaf Sets (贪心+树上构造)
题目大意:给你一棵树,让你对叶节点分组,保证每组中,任意两个叶节点之间的距离不大于K,求最小的组数
手动yy的贪心竟然对的
对于每个节点,维护一个$ma[i]$,表示在$i$节点的子树内 未被分组的叶节点到$i$节点的最长距离
那么,对于每个节点,把它的子节点按照$ma[i]$排序,那么如果这个点的子树不需要额外的分组,就要保证最大的$ma[v1]$和次大的$ma[v2]$之间的距离小于等于K
如果不满足,说明需要对子树内的节点进行额外分组
根据贪心的思想,选择ma最大的子节点$v1$,那么就从小往大一直找满足$ma[v1]+ma[vj]<=K$的点,当不满足条件时,说明刚才找过的小节点和那个较大的节点可以分成一组。接下来,要看次大$v2$的点能否满足更次大$v3$能否满足$ma[v2]+ma[v3]<=K$,找到说明可行,回溯。否则要继续刚才的过程,直到剩余子节点之间的最长距离<=K
因为每个节点只会以这种方式被遍历到一次,所以并不需要二分
1号节点可能是叶节点,所以不能直接把1当成根
另外,如果根节点的ma>1,说明根节点还剩下一些节点没被分组,把它们分到一组即可
1 #include <vector> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define ll long long 6 #define N 1001000 7 #define uint unsigned int 8 #define inf 0x3f3f3f3f3f3f3fll 9 using namespace std; 10 //re 11 int gint() 12 { 13 int ret=0,fh=1;char c=getchar(); 14 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 15 while(c>='0'&&c<='9'){ret=(ret<<3)+(ret<<1)+c-'0';c=getchar();} 16 return ret*fh; 17 } 18 19 int n,m,cte,num,S; 20 int head[N],fa[N],inc[N]; 21 struct Edge{int to,nxt;}edge[N*2]; 22 23 void ae(int u,int v){ 24 cte++;edge[cte].to=v,inc[v]++; 25 edge[cte].nxt=head[u],head[u]=cte; 26 } 27 28 vector<int>to[N]; 29 int ma[N]; 30 int cmp(int x,int y){return ma[x]<ma[y];} 31 int solve(int u){ 32 int ans=0,l,r; 33 for(int j=head[u];j;j=edge[j].nxt) 34 { 35 int v=edge[j].to; 36 if(v==fa[u]) continue; 37 to[u].push_back(v); 38 ans+=solve(v); 39 } 40 int tot=to[u].size(); 41 sort(to[u].begin(),to[u].end(),cmp); 42 if(!tot){ma[u]=1;return 0;} 43 if(tot==1){ma[u]=ma[to[u][tot-1]];} 44 else if(ma[to[u][tot-1]]+ma[to[u][tot-2]]<=m) 45 ma[u]=ma[to[u][tot-1]]; 46 else{ 47 l=0,r=tot-1; 48 while(r>0&&l<r&&ma[to[u][r]]+ma[to[u][r-1]]>m){ 49 for(;l<r&&ma[to[u][r]]+ma[to[u][l]]<=m;l++); 50 r--,ans++; 51 }ma[u]=ma[to[u][r]]; 52 }ma[u]+=(ma[u]>0?1:0);return ans; 53 } 54 55 56 int main() 57 { 58 scanf("%d%d",&n,&m); 59 int x,y; 60 for(int i=1;i<n;i++) 61 x=gint(),y=gint(),ae(x,y),ae(y,x); 62 for(int i=1;i<=n;i++) 63 if(inc[i]!=1) {S=i;break;} 64 dep[S]=1,dfs1(S,-1); 65 tp[S]=1,dfs2(S); 66 int ans=solve(S); 67 if(ma[S]-1>0) ans++; 68 printf("%d\n",ans); 69 return 0; 70 }
转载于:https://www.cnblogs.com/guapisolo/p/9812742.html
CF1042F Leaf Sets (贪心+树上构造)相关推荐
- [CF1042F]Leaf Sets
题目大意:给定一棵$n$个点的树,将叶子节点分为数个集合,使集合里点对最长距离不超过$k$,求最少集合数. 题解:贪心,发现将叶子节点分成集合等于把节点划分集合,答案是一样的.因为一定有一个点,到非叶 ...
- c++实现贪心法构造最大整数问题
c++实现贪心法构造最大整数问题 问题描述: 问题描述: 求给定非负整数序列中的数字排列成的最大数字. 例如: 输入:{50,2,1,9} 输出:95021 思路: 采用贪心算法,先将所有整数转换成字 ...
- c++ 贪心法构造货币统计问题
c++ 贪心法构造货币统计问题 问题描述: 问题描述: 某单位为每个员工发工资(精确到元),为了保证不要临时兑换零钱, 且取款的张数最少,取工资前要统计出所有职工的工资所需各种币值(100,50,20 ...
- HDU 5385 The path(贪心、构造、最短路径树)
HDU 5385 题目大意:给定一个图,dis表示第i个点到1点的最短路,dis1=0,给有向图上的边赋权值(1~n)满足dis1<dis2<dis3<--<disk>d ...
- CodeForces - 967D Resource Distribution(贪心+二分+构造)
题目链接:点击查看 题目大意:给出 n 个机器,每个机器可以处理 a[ i ] 的工作,现在有两个工作需要处理,工作量分别为 x1 和 x2,可以将一个工作分配给 k 个机器同时完成,需要满足: k ...
- 【CodeForces - 545 ABCDE套题训练题解】贪心, 构造,模拟,dp,最短路树(Dijkstra+变形)
A: 题干: Input The first line contains integer n (1 ≤ n ≤ 100) - the number of cars. Each of the next ...
- 【牛客 - 317B】小a与204(贪心,构造,水题)
题干: 小a非常喜欢204204这个数字,因为′a′+′k′=204′a′+′k′=204. 现在他有一个长度为nn的序列,其中只含有2,0,42,0,4这三种数字 设aiai为序列中第ii个数,你需 ...
- CF722D. Generating Sets[贪心 STL]
D. Generating Sets time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- cf:D. The Enchanted Forest【贪心 + 模拟 + 构造】
分析 找规律然后构造才是王道(分类讨论) 如果k小于等于n,说明不会来回走,所以不会影响增量,只需要找到最大的连续k个即可 可用accumulate操作,注意如果initial = 0的话,最后是会有 ...
最新文章
- Philip S. Yu 讲的广度学习到底是什么?
- WEB前端:浏览器(IE+Chrome+Firefox)常见兼容问题处理【03】
- Basic:三层架构开发
- boot spring 怎么执行hql_spring-boot 中使用graphql的正确姿势
- ora错误匹配java_上周上线碰见的ORA-00054错误回放
- 【英语学习】【WOTD】sentient 释义/词源/示例
- 数据科学和人工智能技术笔记 十三、树和森林
- ci 页面php代码,Cicool v3.1.0 - PHP页面、表单、API、CRUD生成器
- 天翼云盘php插件,Linux下使用天翼云盘终极方案
- android系统图标大小
- C# asp.net常见编译|运行错误
- Linux环境下虚拟化之KVM常用命令
- 编译OpenJDK8:configure: Could not compile and link with freetype. This might be a 32/64-bit mismatch.
- java 进度条 百分比_java怎么让进度条带百分数
- Java程序设计实验三 面向接口编程
- 简述完整的计算机组成部分组成部分组成,简述计算机系统的组成
- 使用certbot自动续签ssl证书
- 遥感影像识别-成像合成
- Angular6笔记(4)
- IDEA的好用小工具Test RESTful web Service