bzoj4027: [HEOI2015]兔子与樱花
2015-10-29 09:50
316 查看
传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=4027
思路:自底向上贪心。
设f[i]表示i的子树中最多能删多少点,
g[i]表示i的子树删去f[i]个点后的重量。
每次给儿子按g[son[i]]排序,贪心地从小到大删,直到不能删。
为什么可以这样做?
因为删下面的比删上面的点不会更差,
如果因为按贪心删了儿子而导致这个点不能再删,那么我们只会损失一个点,就是该点。
而删除儿子至少会删除一个,所以不会亏。
思路:自底向上贪心。
设f[i]表示i的子树中最多能删多少点,
g[i]表示i的子树删去f[i]个点后的重量。
每次给儿子按g[son[i]]排序,贪心地从小到大删,直到不能删。
为什么可以这样做?
因为删下面的比删上面的点不会更差,
如果因为按贪心删了儿子而导致这个点不能再删,那么我们只会损失一个点,就是该点。
而删除儿子至少会删除一个,所以不会亏。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> const int maxn=2000010,maxm=maxn<<1; using namespace std; int n,m,pre[maxm],now[maxn],son[maxm],tot,c[maxn],a[maxn],ans; bool ok;char ch; void read(int &x){ for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); if (ok) x=-x; } void add(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;} void dfs(int x){ for (int y=now[x];y;y=pre[y]) dfs(son[y]); int cnt=0; for (int y=now[x];y;y=pre[y]) a[++cnt]=c[son[y]]; sort(a+1,a+1+cnt); for (int i=1;i<=cnt;i++){ if (c[x]+a[i]-1>m) break; c[x]+=(a[i]-1),ans++; } } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) read(c[i]); for (int i=1,x,num;i<=n;i++){ read(num),c[i]+=num; for (int j=1;j<=num;j++) read(x),x++,add(i,x); } dfs(1),printf("%d\n",ans); //for (int i=1;i<=n;i++) printf("%d %d %d\n",i,f[i],g[i]); return 0; }
相关文章推荐
- win2012的VMQ好像是鸡肋
- mybatis例子及mybatis和spring整合
- 用python求解一元二次方程组
- Android 反编译
- Linux 软链接和硬链接的理解与学习
- 最好的科普著作《追寻记忆的痕迹》——神经与精神的历史和未来
- 更新游戏后还是那个storage的数据
- 包裹bug问题但是浏览器能玩
- 命令下运行jar包
- java保留2位小数
- c++文件读写
- 字节码
- apply方法和spray的dsl理解
- 克鲁斯卡算法 并查集实现最小生成树(伪代码)
- Linux修改主机名称
- MyISAM 表的index blocks 是buffered 和被所有的threads 共享。
- SIFT特征检测
- TIOBE 2015年10月编程语言排行榜 Ruby进入TIOBE排行榜前十
- CentOS6.5安装telnet
- vs下取得资源文件中的版本信息