RT,考虑记录每个进过的点的出度和,当前节点的深度为 d。那么我只要 出度和 <d∗k (k 为二分的值即可)。
求大佬们 hack, 交上去只有 80pts
#include <bits/stdc++.h>
using namespace std;
#define N 300010
#define ll long long
#define int long long
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
a = x * s;
return ;
}
int n;
struct node{
int v, next;
} t[N << 1];
int f[N];
int bian = 0;
inline void add(int u, int v){
t[++bian] = (node){v, f[u]}, f[u] = bian;
return ;
}
int sum = 0;
bool flag = 0;
int deth[N];
int du[N];
#define v t[i].v
void prepare(int now, int father){
deth[now] = deth[father] + 1;
for(int i = f[now]; i; i = t[i].next){
if(v != father){
prepare(v, now);
du[now]++;
}
}
return ;
}
bool dfs(int now, int father, int lim){
if(deth[now] * lim >= n) return 1;
if(sum > deth[now] * lim) return 0;
sum += du[now];
bool flag = 1;
for(int i = f[now]; i; i = t[i].next){
if(v != father)
flag &= dfs(v, now, lim);
}
sum -= du[now];
return flag;
}
#undef v
bool check(int lim){
sum = 0;
return dfs(1, 0, lim);
}
signed main(){
// freopen("hh.txt", "r", stdin);
read(n);
for(int i = 1; i < n; i++){
int x, y;
read(x), read(y);
add(x, y); add(y, x);
}
prepare(1, 0);
int l = 0, r = n, ans = 0;
while(l <= r){
int mid = l + r >> 1;
if(check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
cout << ans << endl;
return 0;
}