NKOJ 死亡的颂唱者【贪心】

每次取深度最大的点向上跳 m m 次的点为温泉点:

#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=1e3+5;

ll t,n,m,s,ans,num,f[N],cover[N];

vector<ll>ed[N],dep[N];

inline ll read() {
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

ll gf(ll x) {
	rep(i,1,m) x=f[x];return x;
} 

void dfs1(ll x,ll fa,ll dis) {
	f[x]=fa;
	
	if(ed[x].size()==1&&dis>m) dep[dis].push_back(x);
	
	repl(i,0,ed[x].size()) if(ed[x][i]!=fa) dfs1(ed[x][i],x,dis+1);
}

void dfs2(ll x,ll fa,ll dis) {
	cover[x]=1;
	if(dis==m) return ;
	repl(i,0,ed[x].size()) if(ed[x][i]!=fa) dfs2(ed[x][i],x,dis+1);
}

void init() {
	n=read(),s=read(),m=read();ans=num=0;
	
	memset(cover,0,sizeof(cover));
	rep(i,0,n) ed[i].clear(),dep[i].clear();
	
	
	repl(i,1,n) {
		ll x=read(),y=read();
		ed[x].push_back(y),ed[y].push_back(x);
	}
}

void solve() {
	dfs1(s,-1,0);
	dfs2(s,-1,0);
	
	repd(i,n,m+1) repl(j,0,dep[i].size()) {
		if(cover[dep[i][j]]) continue;
		ans++;ll fa=dep[i][j];
		rep(k,1,m) fa=f[fa];dfs2(fa,-1,0);		
	}
	
	printf("%lld\n",ans);
}

int main() {
	t=read();
	
	while(t--) {
		init();
		solve();
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/82820589