题意:给你一棵树,让你把这些树上的节点用M种颜色染,然后问你在最优的染色方案下,相同颜色点连接的最小边集的交集最大是多少。
就是问一条边上的两端,如果上端的点数大于k,并且下端的点数小于k,那么这条边将计数。
先用DFS求出每个点的子孙节点个数(包括自身),假设为x,那么它的上面点的个数为n-x,只要x>=k&&(n-x)>=k,ans++。
#include<bits/stdc++.h>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
typedef long long ll;
const int maxn = 200005;
int n,k,ans;
int num[maxn];
vector<int>vec[maxn];
void dfs(int u,int pre)
{
num[u]=1;
for(int i=0;i<vec[u].size();i++)
{
int v=vec[u][i];
if(v==pre) continue;
dfs(v,u);
num[u]+=num[v];
}
}
int main()
{
int u,v;
rush()
{
mst(num,0);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
vec[i].clear();
}
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
vec[u].push_back(v);
vec[v].push_back(u);
}
ans=0;
dfs(1,-1);
for(int i=1;i<=n;i++)
if(num[i]>=k&&n-num[i]>=k)
ans++;
printf("%d\n",ans);
}
return 0;
}