[CF1042F] Leaf Sets

题目传送门

这个问题可以用贪心解决。

可以发现,每个节点的所有叶子节点中,真正起约束作用的是深度最大的那个。

因为大的满足了,小的一定也满足。

这样dfs函数返回一个当前点最深的叶子的距离即可。

每次处理完所有子节点之后排个序就行了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int n,k;
 7 int hd[1000005],to[2000005],nx[2000005],ec;
 8 int deg[1000005];
 9 
10 int read()
11 {
12     int ret=0;char c=getchar();
13     while(c<'0'||c>'9')c=getchar();
14     while(c>='0'&&c<='9')ret=ret*10+c-'0',c=getchar();
15     return ret;
16 }
17 
18 void edge(int af,int at)
19 {
20     to[++ec]=at;
21     nx[ec]=hd[af];
22     hd[af]=ec;
23     deg[at]++;
24 }
25 
26 int st[1000005],tp;
27 int ans;
28 
29 int dfs(int p,int fa)
30 {
31     if(deg[p]==1)return 0;
32     int l=tp+1;
33     tp+=deg[p]-1;
34     int r=l;
35     for(int i=hd[p];i;i=nx[i])
36         if(to[i]!=fa)
37             st[r++]=dfs(to[i],p)+1;
38     r--;
39     sort(st+l,st+r+1);
40     while(r-l&&st[r]+st[r-1]>k)r--,ans++;
41     return st[r];
42 }
43 
44 int main()
45 {
46     scanf("%d%d",&n,&k);
47     for(int i=1;i<n;i++)
48     {
49         int ff=read(),tt=read();
50         edge(ff,tt);
51         edge(tt,ff);
52     }
53     int root=1;
54     for(;deg[root]==1;root++);
55     dfs(root,root);
56     printf("%d",ans+1);
57     return 0;
58 }

 

posted @ 2018-10-22 21:07  cervusky  阅读(148)  评论(0编辑  收藏  举报

Contact with me