zoukankan      html  css  js  c++  java
  • bzoj 2067 [Poi2004]SZN——二分+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2067

    最少的线段可以贪心地想出来。(结果还是写错了)就是偶数孩子可以自己配对,奇数孩子要带一个上去;算条数的时候在该条拐弯或截止的时候算,就是每个点的度数减1除以2求和,最后加上1表示根节点。

    还以为第二问能贪心做呢。结果WA。奇数孩子带一个最小的上去是不行的;偶数孩子都不带上去也是不行的。

    于是二分一下答案。结果WA。偶数孩子带一个尽量小的上去还能贪心,奇数孩子并不是用中间那个孩子与别的孩子配对使得自己带一个尽量小的孩子上去。

    奇数孩子不知带哪个孩子上去,像这种就应该考虑枚举、二分之类暴力一点的做法。枚举的话可能n^2,所以二分一下,判断就是去掉这个孩子,剩下的贪心配对。

    顺便把偶数孩子的那个“带0上去”也作为一个孩子加进去,就很方便了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e4+5;
    int n,hd[N],xnt,to[N<<1],nxt[N<<1],rt,l,r,mid;
    int deg[N],dis[N],ans,sta[N],top;
    bool flag;
    int rdn()
    {
        int ret=0;bool fx=1;char ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
        while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
        return fx?ret:-ret;
    }
    void add(int x,int y)
    {
        to[++xnt]=y; nxt[xnt]=hd[x]; hd[x]=xnt;
        to[++xnt]=x; nxt[xnt]=hd[y]; hd[y]=xnt;
        deg[x]++; deg[y]++;
    }
    void dfs(int cr,int fa)
    {
        for(int i=hd[cr],v;i;i=nxt[i])
            if((v=to[i])!=fa)
            {
                dfs(v,cr);
                if(flag)return;
            }
    
        top=0;
        for(int i=hd[cr];i;i=nxt[i])
            if(to[i]!=fa)
                sta[++top]=dis[to[i]]+1;
        if(deg[cr]&1) sta[++top]=0;//偶数孩子可以0地向上
        sort(sta+1,sta+top+1);
    
        if(cr==1)
        {
            for(int i=1,j=top;i<j;i++,j--)
                if(sta[i]+sta[j]>mid)
                {flag=1;return;}
            return;
        }
    
        int tl=1,tr=top,ret=-1;
        while(tl<=tr)
        {
            int tmid=tl+tr>>1; bool fg=0;
            for(int i=1,j=top;i<j;i++,j--)
            {
                if(i==tmid) i++; if(j==tmid) j--;
                if(sta[i]+sta[j]>mid){fg=1;break;}
            }
            if(!fg) ret=tmid,tr=tmid-1;
            else tl=tmid+1;
        }
        if(ret==-1)flag=1;
        else dis[cr]=sta[ret];
    }
    int main()
    {
        n=rdn();
        for(int i=1,u,v;i<n;i++)
        {
            u=rdn(); v=rdn(); add(u,v);
        }
    //    for(int i=2;i<=n;i++) ans+=deg[i]>>1;
    //    ans+=(deg[1]==1?0:(deg[1]+1)>>1);
        for(int i=1;i<=n;i++) ans+=((deg[i]-1)>>1);
        printf("%d ",ans+1);
        r=n;
        while(l<=r)
        {
            mid=l+r>>1; flag=0;
            dfs(1,0);
            if(!flag) ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    微软官方Silverlight5新特性完整介绍
    Windows Phone 7外包(承接WP7项目外包 可签合同 长期有效)
    我们为什么要选择Silverlight?(CSDN网友的见解分享大家)【转】
    开博记录02120928
    [转载]在linux下如何制作img的映像文件
    JavaScript中的null和undefined
    年度映像
    25岁毕业,拿一万块钱月薪
    saymedia bug问题
    mxp组件开发及jsfl文件
  • 原文地址:https://www.cnblogs.com/Narh/p/9690512.html
Copyright © 2011-2022 走看看