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
",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
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/yanlifneg/p/6043526.html