P3915 树的分解
题意:将一棵树分成N/K个连通块,每个块有K个点。
题解:容易知道,从下往上遍历,连通块一定是个子树,直接dfs遇到满足的连通块计数,并将该子树所含点清零。
/*
author : mxylulu
date : 2019/2/21
says : 唯有全力以赴。
*/
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define RFOR(i,a,b) for(int i=a;i>=b;i--)
#define sf(i) scanf("%d",&i)
#define pf(i) printf("%d ",i)
using namespace std;
typedef long long LL;
int N,K;
int T;
bool ok;
vector<int>G[100050];
int dis[100050];
int tot;
void dfs(int u,int last)
{
int num=0;
for(auto v:G[u])
if(v!=last)
{
dfs(v,u);
num+=dis[v];
}
dis[u]=num+1;
if(dis[u]==K)tot++,dis[u]=0;
if(dis[u]>K)ok=false;
}
int main()
{
cin>>T;
while(T--)
{
cin>>N>>K;
ok = true;tot = 0;
memset(dis,0,sizeof(dis));
FOR(i,1,N)G[i].clear();
FOR(i,1,N-1)
{
int x,y;
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
if(N%K!=0)puts("NO");
else
{
dfs(1,1);
if(tot!=N/K)ok=false;
if(ok)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
system("pause");
}