CF1042F Leaf Sets

原题链接:http://codeforces.com/contest/1042/problem/F

Leaf Sets

You are given an undirected tree, consisting of n n 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 k k k.

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 n n n and k ( 3 ≤ n ≤ 1 0 6 , 1 ≤ k ≤ 1 0 6 ) k (3≤n≤10^6, 1≤k≤10^6) k(3n106,1k106) — the number of vertices in the tree and the maximum distance between any pair of leaves in each beautiful set.

Each of the next n − 1 n−1 n1 lines contains two integers v i v_i vi and u i ( 1 ≤ v i , u i ≤ n ) u_i (1≤v_i,u_i≤n) ui(1vi,uin) — the description of the i i i-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:

题解

对于每个点维护最深的叶子离自己的距离,向上合并时,将所有儿子按最深的叶子离自己的距离排序,从深到浅遍历尝试合并,如果相邻的两个距离加起来大于 k k k,便无法合并,向上传也没有意义,于是就将该儿子及其子树单独分成一个集合,答案+1,最后返回在删去所有分离的儿子后最深的叶节点离自己的距离。

代码
#include<bits/stdc++.h>
#define add(a,b) mmp[a].push_back(b)
using namespace std;
const int M=1e6+5;
int ans,n,k;
vector<int>mmp[M];
int dfs(int f,int v)
{
	if(mmp[v].size()==1)return 0;
	vector<int>tmp;
	for(int i=mmp[v].size()-1;i>=0;--i)if(mmp[v][i]!=f)tmp.push_back(dfs(v,mmp[v][i])+1);
	sort(tmp.begin(),tmp.end());
	for(int siz;(siz=tmp.size())>1&&tmp[siz-1]+tmp[siz-2]>k;++ans,tmp.pop_back());
	return tmp.back();
}
void in(){scanf("%d%d",&n,&k);for(int i=1,a,b;i<n;++i)scanf("%d%d",&a,&b),add(a,b),add(b,a);}
void ac(){for(int i=1;i<=n;++i)if(mmp[i].size()>1)dfs(0,i),printf("%d",ans+1),exit(0);}
int main(){in(),ac();}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值