【HDOJ6228】Tree(树)

题意:有一棵n个点的树,在树上的点涂色,每个点涂一种颜色,一共可以涂k种颜色,

然后把同一种颜色(比如说x)的点用最优方案连起来,在连线的边涂上x颜色,问涂k次的边最多有几条

k<=500

sigma n<=200000

思路:类似边分治的思路

考虑每一条边,如果以它为中心将树分割出的两部分点数都不小于k的话这条边必定对答案有贡献

这场都是队友写的,划水真爽

 1 #include <stdio.h>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string.h>
 5 #include <limits.h>
 6 #include <string>
 7 #include <iostream>
 8 #include <queue>
 9 #include <math.h>
10 #include <stack>
11 #include <map>
12 #define left (now<<1)
13 #define right ((now<<1)+1)
14 #define mid ((l+r)>>1)
15 using namespace std;
16 typedef long long int lint;
17 
18 const int MAXN = 2e5 + 10;
19 const int MOD = 1e9 + 7;
20 const int EPS = 1e-8;
21 
22 int n,t,s[MAXN];
23 int ans1,ans2,ans,k;
24 vector<int> g[MAXN];
25 
26 int dfs(int fa,int now){
27     s[now] = 1;
28     if(g[now].size() == 1 && now != 1){ return s[now];}
29     for(int i = 0; i < g[now].size(); ++i){
30         if(g[now][i] != fa){
31             s[now] += dfs(now,g[now][i]);
32         }
33     }
34     return s[now];
35 }
36 
37 int main(){
38     scanf("%d",&t);
39     while(t--){
40         scanf("%d%d",&n,&k); memset(s,0,sizeof(s)); ans = 0;
41         for(int i = 1; i <= n; ++i){g[i].clear();}
42         for(int i = 1; i < n; ++i){
43             int u,v; scanf("%d%d",&u,&v);
44             g[u].push_back(v); g[v].push_back(u);
45         }
46         dfs(-1,1);
47 //        for(int i = 1; i <= n; ++i){
48 //            i != n ? printf("%d ",s[i]) : printf("%d
",s[i]);
49 //        }
50         for(int i = 1; i <= n; ++i){
51             int t1 = s[i]; int t2 = n - t1;
52             if(t1 >= k && t2 >= k) ++ans;
53         }
54         printf("%d
",ans);
55     }
56     return 0;
57 }
原文地址:https://www.cnblogs.com/myx12345/p/9747573.html