zoukankan      html  css  js  c++  java
  • CF1042F Leaf Sets(题解)

    F. Leaf Sets

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

     

     

    You are given an undirected tree, consisting of n vertices.

    The vertex is called a leaf if it has exactly one vertex adjacent to it.

    The distance between some pair of vertices is the number of edges in the shortest path between them.

    Let's call some set of leaves beautiful if the maximum distance between any pair of leaves in it is less or equal to kk.

    You want to split all leaves into non-intersecting beautiful sets. What is the minimal number of sets in such a split?

    Input

    The first line contains two integers nn and kk (3n1e6,1≤k≤1e6) — the number of vertices in the tree and the maximum distance between any pair of leaves in each beautiful set.

    Each of the next n1n−1 lines contains two integers vivi and uiui (1vi,uin1≤vi,ui≤n) — the description of the ii-th edge.

    It is guaranteed that the given edges form a tree.

    Output

    Print a single integer — the minimal number of beautiful sets the split can have.

    Examples
    input
    9 3
    1 2
    1 3
    2 4
    2 5
    3 6
    6 7
    6 8
    3 9
    output
    2
    input
    5 3
    1 2
    2 3
    3 4
    4 5
    output
    2
    input
    6 1
    1 2
    1 3
    1 4
    1 5
    1 6
    output
    5
    Note

    Here is the graph for the first example:

    题解:这道题的题意比较清晰,就不多解释啦。

    对于关于树的问题,有一个很常见的方法:找到一个非叶子节点作为根,然后一边dfs一边处理子树中的问题,一路合并上去。

    若a,b为节点x的儿子,我们假设d_a为以a为根的子树中与a最远的叶子与a的距离(也就是以a为根的子树的深度),d_b同理。

    在判断a、b能否合并时,我们只需要判断da+db+2<=k是否成立即可。假如我们知道x所有儿子的d值,就可以贪心地合并啦-v-

    设x儿子d值的集合(允许重复)为A,如果A中任意两个元素的和都<=k那么答案不会增加,因为没有无法融合的集合。

    但是如果有>k的怎么办?为了解决这个问题,我们需要对A排序,设A中最大元素为d_max1,第二大元素为d_max2,d_max2<=d_max1,

    如果d_max1+d_max2+2>k,说明这两个元素对应子树中的叶子不能放在一个集合里,于是把d_max1从A中删除,ans++。

    为了方便地求出A集合,在dfs时返回删完之后A集合中的最大值就行。

    时间复杂度O(nlogn):对每个节点的所有儿子一遍排序,1e6可能会卡,但是这道题开了3s,欸嘿嘿~

     

    这里是代码↓

     

     1 #include <cstdio>
     2 #include <vector>
     3 #include <algorithm>
     4 #define maxn 1000010
     5 using namespace std;
     6 bool vis[maxn];
     7 int n,k,u,v,ans;
     8 vector<int> ve[maxn];
     9 void add(int x,int y){ve[x].push_back(y);}
    10 int dfs(int x){
    11     vis[x]=1;
    12     if(ve[x].size()==1) return 0;
    13     vector<int> tmp;
    14     for(int i=0;i<ve[x].size();i++){
    15         int v=ve[x][i];
    16         if(!vis[v]) tmp.push_back(dfs(v)+1);
    17     }
    18     sort(tmp.begin(),tmp.end());
    19     while(tmp.size()>1){
    20         int sz=tmp.size();
    21         if(tmp[sz-1]+tmp[sz-2]<=k) break;
    22         ans++,tmp.pop_back();
    23     }
    24     return tmp.back();
    25 }
    26 int main(){
    27     scanf("%d%d",&n,&k);
    28     for(int i=1;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    29     for(int i=1;i<=n;i++)if(ve[i].size()>1){dfs(i);break;}
    30     printf("%d
    ",ans+1);
    31     return 0;
    32 }

     

     

     

  • 相关阅读:
    java中ant包中的org.apache.tools.zip实现压缩和解压缩
    velocity.properties配置说明
    序列化人人网框架下的DAO?也就是在Spring下序列化DAO的问题(spring+quartz集群下)
    vue-cli使用sockjs即时通信
    VUE温习:nextTick、$refs、嵌套路由、keep-alive缓存、is特性、路由属性用法、路由钩子函数
    win7下Google谷歌浏览器上传下载卡死无响应
    微信支付开发流程
    阿里云视频点播同层播放问题
    微信小程序 scroll-view 实现锚点跳转
    解决微信小程序ios端滚动卡顿的问题
  • 原文地址:https://www.cnblogs.com/al76/p/9696542.html
Copyright © 2011-2022 走看看