#include<bitset> #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> typedef long long ll; using namespace std; void Rd(int&res){ res=0;char c; while(c=getchar(),c<48); do res=res*10+(c&15); while(c=getchar(),c>47); } const int N=250001; int head[N],tot_edge; struct Edge{ int to,nxt; }edge[N<<1]; void add_edge(int a,int b){ edge[++tot_edge]=(Edge){b,head[a]}; head[a]=tot_edge; } int n,son[N],mxson[N],heart; void find_heart(int p,int f){ son[p]=1; for(int i=head[p];i;i=edge[i].nxt){ int to=edge[i].to; if(to==f)continue; find_heart(to,p); son[p]+=son[to]; mxson[p]=max(mxson[p],son[to]); } mxson[p]=max(mxson[p],n-son[p]); if(!heart||mxson[heart]>mxson[p])heart=p; } int lim,cnt[505],num[505],tot; ll ans1,ans2; void dfs(int p,int f){ son[p]=1; for(int i=head[p];i;i=edge[i].nxt){ int to=edge[i].to; if(to==f)continue; dfs(to,p); son[p]+=son[to]; } if(heart==f){ if(son[p]<=lim)cnt[son[p]]++; else num[++tot]=son[p]; } ans1+=son[p]-1; } bitset<N>dp; int main(){ Rd(n); for(int i=1,a,b;i<n;i++){ Rd(a),Rd(b); add_edge(a,b); add_edge(b,a); } find_heart(1,0); while(lim*lim<n)lim++; dfs(heart,0); dp[0]=1; while(tot)dp|=dp<<num[tot--]; for(int i=1;i<=lim;i++){ for(int j=cnt[i],k=1;j;j-=k,k<<=1){ if(j<=k){ dp|=dp<<(i*j); break; }else dp|=dp<<(i*k); } } for(int i=1;i<=n;i++) if(dp[i])ans2=max(ans2,1LL*(n-1-i)*i); printf("%d %lld\n",n-1,ans1+ans2); return 0; }
|