zoukankan      html  css  js  c++  java
  • #左偏树,树形dp#洛谷 1552 [APIO2012]派遣

    题目


    分析

    那我指定管理层之后,选择薪水越小的人越好,
    考虑小根堆,由于需要合并,所以采用左偏树


    代码

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N=100011; typedef long long lll;
    struct node{int y,next;}e[N];
    int n,siz[N],lead[N],as[N],et; lll ans,m,c[N];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    struct Leftist_Tree{
    	int rt[N],son[N][2],w[N],d[N];
    	inline signed Merge(int fi,int se){
    		if (!fi||!se) return fi|se;
    		if (w[fi]<w[se]) swap(fi,se);
    		son[fi][1]=Merge(son[fi][1],se);
    		if (d[son[fi][0]]<d[son[fi][1]]) swap(son[fi][0],son[fi][1]);
    		d[fi]=d[son[fi][1]]+1;
    		return fi;
    	}
    	inline signed Pop(int now){
    		rr int t1=son[now][0],t2=son[now][1];
    		rt[t1]=t1,rt[t2]=t2,w[now]=-1,
    		son[now][0]=son[now][1]=d[now]=0;
    		return Merge(t1,t2);
    	}
    }Tre;
    inline void dfs(int x){
    	for (rr int i=as[x];i;i=e[i].next){
    		dfs(e[i].y);
    		Tre.rt[x]=Tre.Merge(Tre.rt[x],Tre.rt[e[i].y]);
    		c[x]+=c[e[i].y],siz[x]+=siz[e[i].y];
    	}
    	while (c[x]>m){
    		c[x]-=Tre.w[Tre.rt[x]],--siz[x],
    		Tre.rt[x]=Tre.Pop(Tre.rt[x]);
    	}
    	ans=max(ans,1ll*lead[x]*siz[x]);
    }
    signed main(){
    	n=iut(),m=iut(),Tre.d[0]=-1;
    	for (rr int i=1;i<=n;++i){
    		rr int F=iut(); if (F) e[++et]=(node){i,as[F]},as[F]=et;
    		c[i]=Tre.w[i]=iut(),Tre.rt[i]=i,lead[i]=iut(),siz[i]=1;
    	}
    	dfs(1);
    	return !printf("%lld",ans);
    } 
    
  • 相关阅读:
    一些可以参考的常用工具库类整理
    Java(Android)线程池 总结
    JAVA泛型
    设计模式总结
    原型模式
    工厂模式与抽象工厂模式
    组合模式
    适配器模式
    建造者模式
    外观模式
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14042107.html
Copyright © 2011-2022 走看看