题意:有一棵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 }