BZOJ 2809 [Apio2012]dispatching
2017-01-20 23:34
337 查看
可并堆
如果固定了管理者,那一定是贪心地选取子树内最小的若干个。因此用大根堆维护子树值,满足总和小于m,然后合并给父亲。
如果固定了管理者,那一定是贪心地选取子树内最小的若干个。因此用大根堆维护子树值,满足总和小于m,然后合并给父亲。
#include<cstdio> #include<algorithm> #define N 100005 #define ll long long using namespace std; namespace runzhe2000 { int n, m, fa , mon , abi , root ; ll ans; struct heap // big root { int ch[2]; ll v; int dis; ll sum; int cnt; }h ; int merge(int x, int y) { if(!x)return y; if(!y)return x; if(h[x].v < h[y].v) swap(x, y); h[x].ch[1] = merge(h[x].ch[1], y); if(h[h[x].ch[0]].dis < h[h[x].ch[1]].dis) swap(h[x].ch[0], h[x].ch[1]); h[x].dis = h[h[x].ch[1]].dis + 1; h[x].sum = h[x].v + h[h[x].ch[0]].sum + h[h[x].ch[1]].sum; h[x].cnt = 1 + h[h[x].ch[0]].cnt + h[h[x].ch[1]].cnt; return x; } int pop(int x){return merge(h[x].ch[0], h[x].ch[1]);} void main() { scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) { scanf("%d%d%d",&fa[i],&mon[i],&abi[i]); root[i] = i; h[i] = (heap){{0,0},mon[i],0,mon[i],1}; } for(int i = n; i; i--) { while(h[root[i]].sum > m) root[i] = pop(root[i]); ll tmp = (ll)h[root[i]].cnt * abi[i]; ans = max(ans, tmp); root[fa[i]] = merge(root[fa[i]], root[i]) ; } printf("%lld\n",ans); } } int main() { runzhe2000::main(); }
相关文章推荐
- BZOJ 2809: [Apio2012]dispatching 左偏树(可合并堆)
- bzoj2809 [Apio2012]dispatching
- BZOJ 2809 APIO 2012 dispatching 平衡树启发式合并
- [可并堆] BZOJ 2809 [Apio2012]dispatching
- BZOJ 2809: [Apio2012]dispatching 可并堆
- [左偏树]BZOJ 2809——[Apio2012]dispatching
- bzoj2809 [Apio2012]dispatching(可并堆)
- BZOJ 2809 [Apio2012]dispatching【可并堆(贪心
- bzoj2809: [Apio2012]dispatching
- [BZOJ2809][Apio2012]dispatching(dfs序+主席树)
- BZOJ 2809: [Apio2012]dispatching [斜堆]
- bzoj2809 [Apio2012]dispatching
- BZOJ 2809 APIO2012 dispatching Treap+启发式合并 / 可并堆
- BZOJ_2809_[Apio2012]dispatching_可并堆
- BZOJ 2809: [Apio2012]dispatching(左偏树)
- bzoj 2809 [Apio2012]dispatching
- 【bzoj2809】 Apio2012—dispatching
- [BZOJ2809][Apio2012]dispatching(可并堆)
- 【bzoj2809】 Apio2012—dispatching
- 【APIO2012】bzoj2809 dispatching