CF1039D You are given a tree

#include <bits/stdc++.h>
const int N=100005;
int edge,last[N],dp[N],ans[N],cnt,n,x,y,Ans,dfn[N],idn,f[N];
struct Edge{
	int to,Next;
}e[N<<1];
void add(int x,int y){
	e[++edge]={y,last[x]};
	last[x]=edge;
}
void dfs(int x,int y){
	dfn[++idn]=x,f[x]=y;
	for (int i=last[x];i;i=e[i].Next){
		int u=e[i].to;
		if (u==y) continue;
		dfs(u,x);
	}
}
int cal(int k){
	int cnt=0;
	for (int i=1;i<=n;i++) dp[i]=1;
	for (int i=n;i>=1;i--){
		int x=dfn[i],ff=f[x];
		if (!dp[x]) continue;
		if (!dp[ff]) continue;
		if (dp[ff] && dp[ff]+dp[x]>=k){
			cnt++;
			dp[ff]=0;
		}else dp[ff]=std::max(dp[ff],dp[x]+1);
	}
	return cnt;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		add(x,y),add(y,x);
	} 
	dfs(1,0);
	int t=(int)sqrt(n*log(n)/log(2));
	t=std::max(t,2);
	ans[1]=n;
	for (int i=2;i<=t;i++)
		ans[i]=cal(i);
	for (int i=t+1;i<=n;i=Ans+1){
		int l=i,r=n;
		ans[l]=cal(l);
		int k=ans[l];
		while (l<=r){
			int mid=(l+r)>>1;
			if (cal(mid)==k) Ans=mid,l=mid+1;
			else r=mid-1;
		}
		for (int j=i;j<=Ans;j++) ans[j]=k; 
	}
	for (int i=1;i<=n;i++) printf("%d
",ans[i]);
}
* 生而自由 爱而无畏 *
原文地址:https://www.cnblogs.com/flyfeather6/p/14381120.html