rt,我的思路是设 fu 表示考虑当前硬币在 u 节点,最多可以多少轮不管 u 子树,然后再对这个子树进行操作,使得硬币不能到达 dis=k 的点
转移就把 fv 放在一起排序,取 fv 减去 fv 在排序后数组的位置的最小值
感觉做法有点假,但是过了,求 hack / 证明正确性
//when you use vector or deque,pay attention to the size of it.
//by OldDirverTree
#include<bits/stdc++.h>
//#include<atcoder/all>
#define P pair<int,int>
#define int long long
#define mid (l+r>>1)
using namespace std;
//using namespace atcoder;
const int N=401,inf=1e9;
int n,m,dis[N],f[N];
vector<int> G[N];
struct custom_hash
{
static uint64_t splitmix64(uint64_t x) {
x+=0x9e3779b97f4a7c15;
x=(x^(x>>30) )*0xbf58476d1ce4e5b9;
x=(x^(x>>27) )*0x94d049bb133111eb;
return x^(x>>31);
}
size_t operator() (uint64_t x) const {
static const uint64_t FIXED_RANDOM=chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x+FIXED_RANDOM);
}
};
int read() {
int x=0; char c=0; while (!isdigit(c) ) c=getchar();
while (isdigit(c) ) x=(x<<3)+(x<<1)+(c&15),c=getchar();
return x;
}
void dfs(int u,int fa)
{
f[u]=inf; vector<int> w;
if (dis[u]==m) f[u]=-1;
for (int v:G[u]) if (v^fa) {
dis[v]=dis[u]+1,dfs(v,u);
w.push_back(f[v]+1);
}
sort(w.begin(),w.end() );
for (int i=0;i<w.size();i++) f[u]=min(f[u],w[i]-i);
if (f[u]<0) f[u]=-1;
}
main()
{
n=read(),m=read();
for (int i=1;i<n;i++) {
int x=read(),y=read();
G[x].push_back(y),G[y].push_back(x);
}
dfs(1,0);
printf(~f[1]?"DA":"NE");
return 0;
}