【bzoj2809】[Apio2012]dispatching
2017-01-12 18:11
465 查看
= =这道题调了好多遍才过。
其实分析一下这道题还是蛮简单的。
首先建图的时候我们把每个忍者作为一个点,我们可以发现,每个忍者的入度都为1(除了master),所以我们对其进行dfs,可以保证每个点只被遍历到一遍。
其次,这道题是可以贪心的,一方面这道题的结果为忍者个数*领导力,所以我们可以选择薪酬尽量小的忍者,另一方面,在dfs树中处于上端的忍者可以选择所有下端的忍者,也就是说,我们可以维护一个大根堆,堆中含有下层搜索树中的所有点,每次插入此时正在遍历的点,然后弹出权值最大的点直到堆中所有权值之和小于总薪酬。
如上分析,所以应该用一个可并堆,于是使用左偏树,跑的很快,交了很多遍是因为一直wa发现最后自己的merge写错了QAQ.
其实分析一下这道题还是蛮简单的。
首先建图的时候我们把每个忍者作为一个点,我们可以发现,每个忍者的入度都为1(除了master),所以我们对其进行dfs,可以保证每个点只被遍历到一遍。
其次,这道题是可以贪心的,一方面这道题的结果为忍者个数*领导力,所以我们可以选择薪酬尽量小的忍者,另一方面,在dfs树中处于上端的忍者可以选择所有下端的忍者,也就是说,我们可以维护一个大根堆,堆中含有下层搜索树中的所有点,每次插入此时正在遍历的点,然后弹出权值最大的点直到堆中所有权值之和小于总薪酬。
如上分析,所以应该用一个可并堆,于是使用左偏树,跑的很快,交了很多遍是因为一直wa发现最后自己的merge写错了QAQ.
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=100010; int tot=0,cnt=0,head ,c ,root ; int n,m,l ; long long ans=0,sum ,size ; struct edge{ int u,v,next; }e[100010]; int add(int u,int v){ e[++tot].u=u; e[tot].v=v; e[tot].next=head[u]; head[u]=tot; } struct Lefttree{ int dis ,rc ,lc ,v ; int merge(int x,int y) { if (!x||!y)return x+y; int tmp; if (v[x]<v[y])tmp=x,x=y,y=tmp; rc[x]=merge(rc[x],y); if (!lc[x]||dis[rc[x]]>dis[lc[x]])tmp=rc[x],rc[x]=lc[x],lc[x]=tmp; if(rc[x])dis[x]=dis[rc[x]]+1; else dis[x]=0; return x; } void pop(int &x){ x=merge(lc[x],rc[x]); } int top(int x){ return v[x]; } }lt; inline int F(){ register int aa,bb;register char ch; while(ch=getchar(),ch!='-'&&(ch>'9'||ch<'0'));ch=='-'?aa=bb=0:(aa=ch-'0',bb=1); while(ch=getchar(),ch>='0'&&ch<='9')aa=(aa<<3)+(aa<<1)+ch-'0';return bb?aa:-aa; } void dfs(int u) { size[u]=1;sum[u]=c[u]; root[u]=++cnt;lt.v[cnt]=c[u]; for (int i=head[u];i;i=e[i].next) { dfs(e[i].v); size[u]+=size[e[i].v]; root[u]=lt.merge(root[u],root[e[i].v]); sum[u]+=sum[e[i].v]; } while(sum[u]>m&&size[u]>0) { sum[u]-=lt.top(root[u]); lt.pop(root[u]);size[u]--; } ans=max(ans,size[u]*l[u]*1ll); } int main() { memset(sum,0,sizeof(sum)); n=F();m=F();int v; for (int i=1;i<=n;i++) { v=F(),c[i]=F(),l[i]=F(); add(v,i); } dfs(1); cout<<ans; return 0; }
相关文章推荐
- 在VM虚拟机中安装CentOS
- 程序调试的利器—日志
- 判断一条单向链表是不是“回文”
- sql case when then
- 【SSH网上商城项目实战14】商城首页UI的设计
- 矩阵第一章总结笔记
- 判断一条单向链表是不是“回文”
- eclipse中怎么安装spring插件
- C链栈实现
- Android使用ViewPager实现带指示点的页面导航效果
- 【SSH网上商城项目实战13】Struts2实现文件上传功能
- 优雅实现RecyclerView多种布局
- C链栈实现
- 奇异值分解(SVD)
- 是AI就躲个飞机-纯Python实现人工智能
- CentOS6.5PXE自动部署
- Java的发展历史
- 计算Java对象在内存中占用空间
- laravel 数据库操作(表、字段)
- 特殊权限之sticky