BZOJ 2097: [Usaco2010 Dec]Exercise 奶牛健美操 二分 + 贪心 + 树上问题
Code:
#include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in","r",stdin) #define maxn 1000000 int n,S,edges,mid,cnt; int hd[maxn],to[maxn<<1],nex[maxn<<1],dis[maxn]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs(int u,int ff) { if(cnt>S) return; int now=0; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; dfs(v,u); if(now+dis[v] > mid) { ++cnt; now=min(now, dis[v]); } else now=max(now, dis[v]); } dis[u]=now+1; } int check() { cnt=0; dfs(1,0); return cnt<=S; } int main() { // setIO("input"); int i,j; scanf("%d%d",&n,&S); for(i=1;i<n;++i) { int a,b; scanf("%d%d",&a,&b); add(a,b),add(b,a); } int l=1,r=n,ans=0; while(l<=r) { mid=(l+r)>>1; if(check()) ans=mid, r=mid-1; else l=mid+1; } printf("%d\n",ans); return 0; }