zoukankan      html  css  js  c++  java
  • HEOI2015 兔子与樱花

    Time Limit: 10 Sec Memory Limit: 256 MB

    Description

    很久很久之前,森林里住着一群兔子。有一天,兔子们突然决定要去看樱花。兔子们所在森林里的樱花树很特殊。樱花树由(n)个树枝分叉点组成,编号从(0)(n-1),这(n)个分叉点由(n-1)个树枝连接,我们可以把它看成一个有根树结构,其中(0)号节点是根节点。这个树的每个节点上都会有一些樱花,其中第(i)个节点有(c_i)朵樱花。樱花树的每一个节点都有最大的载重(m),对于每一个节点(i),它的儿子节点的个数和i节点上樱花个数之和不能超过(m),即(son(i) + c_i leq m),其中(son(i))表示(i)的儿子的个数,如果(i)为叶子节点,则(son(i) = 0)

    现在兔子们觉得樱花树上节点太多,希望去掉一些节点。当一个节点被去掉之后,这个节点上的樱花和它的儿子节点都被连到删掉节点的父节点上。如果父节点也被删除,那么就会继续向上连接,直到第一个没有被删除的节点为止。

    现在兔子们希望计算在不违背最大载重的情况下,最多能删除多少节点。

    注意根节点不能被删除,被删除的节点不被计入载重。

    Input

    第一行输入两个正整数,(n)(m)分别表示节点个数和最大载重

    第二行(n)个整数(c_i),表示第(i)个节点上的樱花个数

    接下来(n)行,每行第一个数(k_i)表示这个节点的儿子个数,接下来(k_i)个整数表示这个节点儿子的编号

    Output

    一行一个整数,表示最多能删除多少节点。

    Sample Input

    10 4
    0 2 2 2 4 1 0 4 1 1
    3 6 2 3
    1 9
    1 8
    1 1
    0
    0
    2 7 4
    0
    1 5
    0
    

    Sample Output

    4
    

    HINT

    对于(100\%)的数据,(1 leq n leq 2000000), (1 leq m leq 100000), (0 leq c_i leq 1000)

    数据保证初始时,每个节点樱花数与儿子节点个数之和大于(0)且不超过(m)

    Solution

    我们的重量显然就是樱花数+子节点数。

    我们现在要尽量删最多的点。

    对于一个点(x),它的所有子节点内能删多少点显然与(x)无关。那么我们现在也就只关心它的每个子节点能不能删。

    于是我们可以搞出来一个新数组(c[i])表示当(i)这个点取了最多的点时候的重量。

    然后我们现在把所有子节点都按照(c)值从小到大排序,优先选择比较小的点删除。为什么是对的呢?可以这样考虑吧,如果有一个重量比较大的点没有选,那么事实上我们只会损失掉那个子节点的1个贡献。但是,如果我们选了重量比较小的,有可能会使得整个这个子树的根节点在其父亲那里选不了(这是也只会损失1个贡献),更有可能会使得在其父亲那里可以选(那么就很好什么贡献都不会损失),因此优先选择小的肯定不会差。

    所以我们现在就是采取优先选择(c)值小的点的策略,一定可以得到最优解。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define lowbit(x) ((x)&(-(x)))
    #define REP(i,a,n) for(register int i=(a);i<=(n);++i)
    #define PER(i,a,n) for(register int i=(a);i>=(n);--i)
    #define FEC(i,x) for(register int i=head[x];i;i=g[i].ne)
    #define dbg(...) fprintf(stderr,__VA_ARGS__)
    namespace io{
    	const int SIZE=(1<<21)+1;char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int f,qr;
    	#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    	inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
    	inline int getc(){return gc();}
    	inline void putc(char x){*oS++=x;if(oS==oT)flush();}
    	template<class I>inline void read(I &x){for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;}
    	template<class I>inline void write(I x){if(!x)putc('0');if(x<0)putc('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)putc(qu[qr--]);}
    	inline void print(const char *s){while(*s!='')putc(*s++);}
    	inline void scan(char *s){for(c=gc();c<=' ';c=gc());for(;c>' ';c=gc())*(s++)=c;*s='';}
    	struct Flusher_{~Flusher_(){flush();}}io_flusher_;
    }//orz laofudasuan
    using io::read;using io::putc;using io::write;using io::print;
    typedef long long ll;typedef unsigned long long ull;
    template<typename A,typename B>inline bool SMAX(A&x,const B&y){return x<y?x=y,1:0;}
    template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;}
    
    const int N=2000000+7;
    int n,m,x,y,c[N],ans;
    vector<int>g[N];
    
    inline char cmp(const int&x,const int&y){return c[x]<c[y];}
    inline void DFS(int x){
    	int len=g[x].size(),&cnt=c[x];
    	for(register int i=0;i<len;++i)DFS(g[x][i]);
    	sort(g[x].begin(),g[x].end(),cmp);
    	for(register int i=0;i<len;++i)if(cnt+c[g[x][i]]-1<=m){cnt+=c[g[x][i]]-1;++ans;}else break;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("BZOJ4027.in","r",stdin);freopen("BZOJ4027.out","w",stdout);
    #endif
    	read(n),read(m);
    	for(register int i=1;i<=n;++i)read(c[i]);
    	for(register int i=1;i<=n;++i){
    		read(x);c[i]+=x;
    		for(register int j=1;j<=x;++j)read(y),g[i].push_back(y+1);
    	}
    	DFS(1);write(ans),putc('
    ');
    }
    
  • 相关阅读:
    ruilei.cnblogs 访问量突破20万
    VSTS2008 Load Test Agent
    失落的星球 Lost Planet 秘籍
    C#去除特殊字符串
    Linq Coding Part Nine(IEnumerable、IQueryable、Set)
    Web Services Software Factory tutorial (1 of 5)
    迅雷新闻快讯区JS代码剖析
    Interfaces Topic
    前台如何调用后台事件
    [关注]个税起征点8000元什么时候到来?
  • 原文地址:https://www.cnblogs.com/hankeke/p/BZOJ4027.html
Copyright © 2011-2022 走看看