玄学贪心...

题意:给出一棵树,要求将他的所有叶节点分成最少的组,且在每组中的任意两节点之间的距离不大于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的更多相关文章

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

  2. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  3. cf Round 613

    A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...

  4. ARC下OC对象和CF对象之间的桥接(bridge)

    在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...

  5. [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现

    1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...

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

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

  8. CF #376 (Div. 2) C. dfs

    1.CF #376 (Div. 2)    C. Socks       dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...

  9. CF #375 (Div. 2) D. bfs

    1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...

随机推荐

  1. python(六)列表推导式、字典推导式、集合推导式

    转载 https://www.cnblogs.com/tkqasn/p/5977653.html

  2. linux 文件搜索命令

  3. vue WepApp 音乐App实战以及各个知识点

    1.组件初始化(scoped 貌似属于局域css样式) 2.组件使用三部曲(当然第三步可以<MHeader></MHeader> 也不报错) 3. 配置 路由 ①.在route ...

  4. Table Compression

    https://docs.oracle.com/cd/E11882_01/server.112/e40540/tablecls.htm#CNCPT608

  5. 向量的L2范数求导

    回归中最为基础的方法, 最小二乘法. \[ \begin{align*} J_{LS}{(\theta)} &= \frac { 1 }{ 2 } { \left\| A\vec { x } ...

  6. 搭建Unity安卓开发环境

    原文见 https://blog.csdn.net/chenggong2dm/article/details/20654075 tiny教程 https://docs.unity3d.com/Pack ...

  7. makefile中.PHNOY的用法

    makefile中PHONY的重要性 伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行所在规则定义的命令,有时也可以将一个伪目标称为标签.伪目标通过   PHON ...

  8. 题解-PKUWC2018 Slay the Spire

    Problem loj2538 Solution 在考场上当然要学会写暴力,考虑如果手上已经有了\(a\)张攻击牌和\(b\)张强化牌: 首先强化牌会在攻击牌之前用(废话),其次要将两种牌分别从大往小 ...

  9. js声明引入和变量声明和变量类型、变量

    问题: 在网页的发展历程中,发现网页不能对用户的数据进行自动校验,和提供一些特效. 解决: 使用javascript. 作用 可以让网页和用户进行直接简单的交互. 可以让网页制作特效和动画. 声明js ...

  10. (转!)利用Keras实现图像分类与颜色分类

    2018-07-19 全部谷歌渣翻加略微修改 大家将就的看哈 建议大佬们还是看看原文 点击收获原文 其中用到的示例文件 multi-output-classification 大家可以点击 下载 . ...