C17 左偏树 P1552 [APIO2012] 派遣

视频链接:237 左偏树 派遣_哔哩哔哩_bilibili

Luogu P1552 [APIO2012] 派遣

 

 

复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100005;
int n,m;
int fa[N],pay[N],lead[N]; //原树节点信息
int ls[N],rs[N],dis[N],siz[N],root[N]; //左偏树
long long sum[N],ans;

int merge(int x,int y){
  if(!x||!y) return x+y;
  if(pay[x]<pay[y]) swap(x,y); //大根堆
  rs[x]=merge(rs[x],y);
  
  if(dis[ls[x]]<dis[rs[x]]) swap(ls[x],rs[x]);
  dis[x]=dis[rs[x]]+1;
  return x;
}
int main(){
  scanf("%d%d",&n,&m); dis[0]=-1;
  for(int i=1; i<=n; i++){
    scanf("%d%d%d",&fa[i],&pay[i],&lead[i]);
    root[i]=i; //每个节点看成一个单独的堆
    siz[i]=1;
    sum[i]=pay[i];
    ans=max(ans,1ll*lead[i]);//选一个节点的贡献
  }
  for(int i=n; i>1; i--){ //从叶子节点向上枚举
    int f=fa[i];
    root[f]=merge(root[i],root[f]);
    siz[f]+=siz[i]; sum[f]+=sum[i];
while(sum[f]>m){ //循环删除堆中点权大的节点 siz[f]--; sum[f]-=pay[root[f]]; root[f]=merge(ls[root[f]],rs[root[f]]); } ans=max(ans, 1ll*lead[f]*siz[f]); } cout<<ans; }
复制代码

 

复制代码
// 左偏树+树形DP
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100005;
int n,m;
int pay[N],lead[N]; //原树节点信息
int ls[N],rs[N],dis[N],siz[N],root[N]; //左偏树
long long sum[N],ans;

int h[N],to[N],ne[N],tot;
void add(int a, int b){
  to[++tot]=b;ne[tot]=h[a];h[a]=tot;
}
int merge(int x,int y){
  if(!x||!y) return x+y;
  if(pay[x]<pay[y]) swap(x,y); //大根堆
  rs[x]=merge(rs[x],y);
  
  if(dis[ls[x]]<dis[rs[x]]) swap(ls[x],rs[x]);
  dis[x]=dis[rs[x]]+1;
  return x;
}
void dfs(int x){
  siz[x]=1,sum[x]=pay[x];
  for(int i=h[x]; i; i=ne[i]){
    int y=to[i]; dfs(y);
    root[x]=merge(root[x],root[y]);
    siz[x]+=siz[y]; sum[x]+=sum[y];
  }
  while(sum[x]>m){
    siz[x]--; sum[x]-=pay[root[x]];
    root[x]=merge(ls[root[x]],rs[root[x]]);
  }
  ans=max(ans,1ll*lead[x]*siz[x]);
}
int main(){
  scanf("%d%d",&n,&m);
  dis[0]=-1; int rt;
  for(int i=1,f; i<=n; ++i){
    scanf("%d%d%d",&f,&pay[i],&lead[i]);
    if(f) add(f,i);
    else rt=i;
    root[i]=i; //每个节点看成一个单独的堆
  }
  dfs(rt);
  cout<<ans;
}
复制代码

 

练习:

Luogu P3261 [JLOI2015] 城池攻占

Luogu P3273 [SCOI2011] 棘手的操作

 

posted @   董晓  阅读(189)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-07-15 D31 圆方树 P5236【模板】静态仙人掌
点击右上角即可分享
微信分享提示