Usaco 2010 Dec Gold Exercise(奶牛健美操)
/*codevs 3279 二分+dfs贪心检验 堆版本 re一个 爆栈了*/ #include<cstdio> #include<queue> #include<cstring> #define pa pair<int,int> #define mk make_pair #define X first #define Y second #define maxn 100010 using namespace std; int n,S,num,head[maxn],ans,f[maxn],mid,sum; struct node{ int v,pre; }e[maxn*2]; priority_queue<pa>q; int init(){ int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } void Add(int from,int to){ num++;e[num].v=to; e[num].pre=head[from]; head[from]=num; } void Dfs(int u,int from){ int cnt=0; for(int i=head[u];i;i=e[i].pre){ int v=e[i].v;if(v==from)continue; Dfs(v,u);cnt++; } if(cnt==0)return; while(!q.empty())q.pop(); for(int i=head[u];i;i=e[i].pre){ int v=e[i].v;if(v==from)continue; q.push(mk(f[v],v)); } while(q.size()>=2){ int x=q.top().X,xi=q.top().Y;q.pop(); int y=q.top().X,yi=q.top().Y;q.pop(); if(x+y+2>mid){ f[xi]=0;q.push(mk(y,yi));sum++; } else { q.push(mk(x,xi));q.push(mk(y,yi));break; } } if(q.size()==1&&q.top().X+1>mid){ f[q.top().Y]=0;sum++;q.pop(); } int mx=0; if(q.size())mx=q.top().X+1; f[u]=mx; } bool Judge(){ memset(f,0,sizeof(f)); sum=0;Dfs(1,0); return sum<=S; } int main() { n=init();S=init();int u,v; for(int i=1;i<n;i++){ u=init();v=init(); Add(u,v);Add(v,u); } int l=0,r=0x3f3f3f3f; while(l<=r){ mid=l+r>>1; if(Judge()){ r=mid-1;ans=mid; } else l=mid+1; } printf("%d\n",ans); return 0; }
/*codevs 3279 二分+dfs贪心检验 数组版本*/ #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100010 using namespace std; int n,S,num,head[maxn],ans,f[maxn],mid,sum; struct node{ int v,pre; }e[maxn*2]; struct C{ int o,val; bool operator < (const C &x)const{ return val>x.val; } }p[maxn]; int init(){ int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } void Add(int from,int to){ num++;e[num].v=to; e[num].pre=head[from]; head[from]=num; } void Dfs(int u,int from){ int cnt=0; for(int i=head[u];i;i=e[i].pre){ int v=e[i].v;if(v==from)continue; Dfs(v,u);cnt++; } if(cnt==0)return;cnt=0; for(int i=head[u];i;i=e[i].pre){ int v=e[i].v;if(v==from)continue; p[++cnt]=(C){v,f[v]}; } sort(p+1,p+1+cnt);int p1=1,p2=2; while(p2<=cnt){ int x=p[p1].val,xi=p[p1].o; int y=p[p2].val,yi=p[p2].o; if(x+y+2>mid){ f[xi]=0;sum++;p1++;p2++; } else break; } if(p1==cnt&&p[p1].val+1>mid){ f[p[p1++].o]=0;sum++; } int mx=0; if(p1<=cnt)mx=p[p1].val+1; f[u]=mx; } bool Judge(){ memset(f,0,sizeof(f)); sum=0;Dfs(1,0); return sum<=S; } int main() { n=init();S=init();int u,v; for(int i=1;i<n;i++){ u=init();v=init(); Add(u,v);Add(v,u); } int l=0,r=0x3f3f3f3f; while(l<=r){ mid=l+r>>1; if(Judge()){ r=mid-1;ans=mid; } else l=mid+1; } printf("%d\n",ans); return 0; }