[CF1067B] Multihedgehog 的题解
题目大意
定义 阶刺猬树:
- 对于 阶刺猬树,其中一个点的度 ,其它点的度均为 。
- 对于 阶刺猬树,是在 阶刺猬树的基础上,把所有度为 的点替换成 阶刺猬树,并与原图相连。
给定 个点的树,判断是否是 阶刺猬树。
思路
对于任意 阶刺猬树,有性质:
- 假定 为原始 阶刺猬树的度 的节点,则 到所有叶子节点的距离均为 。
而且只要满足此性质及为 阶刺猬树。
证明:
假设 为 阶刺猬树的度 的节点,那么所有的节点到 的距离均为 。
阶刺猬树则将所有度为 的节点增加一层,及将 到叶子节点的距离增加 。
对于 阶刺猬树, 到叶子的节点均为 阶刺猬树到叶子的节点的距离加 ,所以 阶刺猬树中 到叶子节点的距离为 。
相对的,将所有的叶子节点都向父节点移动,那么如果所有的移动经过 次移动,到最后在一个节点汇合那么这棵树就是 阶刺猬树。
AC Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+6;
int n,k,du[N];
bool vis[N];
vector<int> v[N];
queue<int> q[2];
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>k;
if(k>n){
cout<<"No\n";
exit(0);
}
for(int i=1,x,y;i<n;i++){
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
du[x]++,du[y]++;
}
for(int i=1;i<=n;i++){
if(du[i]==1){
q[1].push(i);
vis[i]=1;
// cout<<i<<' ';
}
}
// cout<<'\n';
// exit(0);
for(int i=1;i<k;i++){
while(!q[i%2].empty()){
int x=q[i%2].front();
q[i%2].pop();
for(int j:v[x]){
if(vis[j]){
continue;
}
if(du[j]<=3){
cout<<"No\n";
exit(0);
}
// cout<<j<<' ';
vis[j]=1;
q[(i+1)%2].push(j);
}
}
// cout<<'\n';
}
int cnt=0,p;
for(int i=1;i<=n;i++){
if(!vis[i]){
cnt++;
p=i;
if(du[i]<3){
cout<<"No\n";
exit(0);
}
}
}
if(cnt==1&&q[k%2].size()==v[p].size()){
cout<<"Yes\n";
}
else{
cout<<"No\n";
}
return 0;
}