CF 1042F
玄学贪心...
题意:给出一棵树,要求将他的所有叶节点分成最少的组,且在每组中的任意两节点之间的距离不大于k
解析:
显然是个贪心啦...
稍微考虑一下贪心思想:
我们从下向上合并整棵树,在合并到某个节点时,我们把他以下的所有叶节点到他的距离全处理出来然后排序,设所有距离排序后为d1,d2...dn
接下来,我们从大到小枚举每个d,如果满足di+di-1+2<=k,那么说明从1到i的所有子节点都可以分到一组里面,而剩下的节点只能单独一个分进一组里了
然后我们向上返回不单独分组的点中距离最大的一个的距离,向上回溯合并即可
画图理解一下:
如图所示,这是一棵树,设k=2
首先我们合并5,6两个点,那么发现这两个点到根的距离都是1,于是我们开心地将这两个点合并到一个集合里,然后回溯
其余最底层节点同理
这是合并前叶节点的状态
这是合并上去第一层的状态
继续合并一层:
于是我们可以继续开心地合并,这时可以发现,所有的次二层节点都无法再合并,这时合并结束,一共需要三个集合
可能这一点不是很好理解,所以我们再假设k=4,那么就可以把2和4合并起来,而3还是无法合并,这样就只需要两个集合了。
总结一下思路:将一个根节点以下的所有叶节点到根节点的距离排序,然后倒序枚举,对于所有的di+di-1+2>=k的部分,我们都要把di单独分组,而剩余的部分可以分进一组,将这一组中的叶节点到这个根节点最长的距离回溯到上一层即可。
证明贪心的正确性:
首先,剩余部分可以分成一组是显而易见的,因为不会有比这更优的方案
而其他的点需要单独分组的原因:假设这些点可以与另一部分子树中的某一部分合并成一个集合,那么根据距离的关系可知,剩下的分成一组的点一定也可以和那一部分合并成一个集合,但这两者却不能合为一个集合,所以无论怎么合并都至少需要两个集合,也就是这样分组一定是某一种最优方案!
这样就完事了
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
struct Edge
{
int next;
int to;
}edge[2000005];
int head[1000005];
int inr[1000005];
int cnt=1;
int n,k;
void init()
{
memset(head,-1,sizeof(head));
cnt=1;
}
void add(int l,int r)
{
edge[cnt].next=head[l];
edge[cnt].to=r;
head[l]=cnt++;
}
int cct=0;
int dfs(int x,int fx)
{
vector<int>v;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
if(to==fx)
{
continue;
}
v.push_back(dfs(to,x)+1);
}
if(v.size()==0)
{
return 0;
}
sort(v.begin(),v.end());
int i;
for(i=v.size()-1;i>=1;i--)
{
if(v[i]+v[i-1]<=k)
{
break;
}
cct++;
}
return v[i];
}
int main()
{
scanf("%d%d",&n,&k);
init();
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
inr[x]++;
inr[y]++;
}
int rot=0;
for(int i=1;i<=n;i++)
{
if(!rot&&inr[i]!=1)
{
rot=i;
break;
}
}
dfs(rot,rot);
printf("%d\n",cct+1);
return 0;
}
CF 1042F的更多相关文章
- ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'
凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- cf Round 613
A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...
- ARC下OC对象和CF对象之间的桥接(bridge)
在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...
- [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现
1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...
- CF memsql Start[c]UP 2.0 A
CF memsql Start[c]UP 2.0 A A. Golden System time limit per test 1 second memory limit per test 256 m ...
- CF memsql Start[c]UP 2.0 B
CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...
- CF #376 (Div. 2) C. dfs
1.CF #376 (Div. 2) C. Socks dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...
- CF #375 (Div. 2) D. bfs
1.CF #375 (Div. 2) D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...
随机推荐
- STL之partition学习
顺便存一下numeric函数的使用方法吧,感觉用处不大. https://blog.csdn.net/baishuo8/article/details/84073565 partition函数,将元素 ...
- 【转载】 python-星号变量的特殊用法
原文链接:https://www.qingsword.com/qing/python-12.html 引言 在Python中,星号除了用于乘法数值运算和幂运算外,还有一种特殊的用法"在变量前 ...
- 【NLP CS224N笔记】汇总
[NLP CS224N笔记]Lecture 1 - Introduction of NLP [NLP CS224N笔记]Lecture 2 - Word Vector Representations: ...
- python模块-----pymysql
一.安装 本模块为python第三方模块,需要单独安装.作用为调用mysql接口执行模块 pip3 install pyMySql 操作步骤: #!/usr/bin/python3 import py ...
- openstack Q版部署-----界面horizon安装(9)
一.界面的安装 控制节点安装软件包: yum install openstack-dashboard -y [root@linux-node1 ~]# vim /etc/openstack-dashb ...
- 使用SQL*Plus连接数据库
About SQL*Plus SQL*Plus is the primary command-line interface to your Oracle database. You use SQL*P ...
- Spring Security测试代码
⒈实体Bean package cn.coreqi.blog.entities; import org.springframework.security.core.GrantedAuthority; ...
- 【转】Python标准模块--importlib
[转]Python标准模块--importlib 作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 P ...
- Linux根文件系统
root :文件系统是文件系统的顶级目录.它必须包含在挂载其它文件系统前需要用来启动 Linux 系统的全部文件.它必须包含需要用来启动剩余文件系统的全部可执行文件和库.文件系统启动以后,所有其他文件 ...
- 在Linux下误删文件后恢复【转】
针对日常维护操作,难免会出现文件误删除的操作.大家熟知linux文件系统不同win有回收站,删除后的文件可以到垃圾箱寻回,要知道linux文件修复比较费劲,网络上面的文档也是五花八门.所以本次研究一种 ...