zoukankan      html  css  js  c++  java
  • [bzoj 2809][Apio2012]dispatching

    传送门

    Solution

    可并堆——左偏树 的模板题

    维护大根堆,这样只要达到雇佣薪水的上限,就直接pop堆顶元素就行了


    Code 

    #include<bits/stdc++.h>
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    #define MN 100005
    int Li[MN],fa[MN],Ci[MN];
    int ls[MN],rs[MN],M,val[MN],siz[MN],rt[MN],dis[MN];
    ll ans,sum[MN];
    struct edge{int to,nex;}e[MN];int hr[MN],en;
    inline void ins(int f,int t){e[++en]=(edge){t,hr[f]};hr[f]=en;}
    int Merge(int x,int y)
    {
    	if(!x||!y) return x|y;
    	if(val[x]<val[y]) std::swap(x,y);
    	rs[x]=Merge(rs[x],y);
    	if(dis[rs[x]]>dis[ls[x]]) std::swap(ls[x],rs[x]);
    	dis[x]=dis[rs[x]]+1;
    	sum[x]=sum[ls[x]]+sum[rs[x]]+val[x];
    	siz[x]=siz[ls[x]]+siz[rs[x]]+1;
    	return x;
    }
    inline void Pop(int &x){x=Merge(ls[x],rs[x]);}
    void dfs(int x)
    {
    	register int i;
    	for(i=hr[x];i;i=e[i].nex)
    	{
    		dfs(e[i].to),rt[x]=Merge(rt[x],rt[e[i].to]);
    		while(sum[rt[x]]>M) Pop(rt[x]); 	
    	}
    	ans=max(ans,1ll*Li[x]*siz[rt[x]]);
    }
    int main()
    {
    	register int n,i;
    	n=read(),M=read();
    	for(i=1;i<=n;++i) fa[i]=read(),Ci[i]=read(),Li[i]=read(),ins(fa[i],i);
    	for(i=1;i<=n;++i) if(Ci[i]<=M) rt[i]=i,sum[i]=val[i]=Ci[i],dis[i]=siz[i]=1;
    	dfs(1);
    	printf("%lld
    ",ans);
    	return 0;
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    Python学习4
    Python学习3
    Python学习2
    表空间
    sqlplus常用设置
    HashMap和LinkedHashMap
    堆栈源码
    观察者模式
    策略模式
    java线性表
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10173082.html
Copyright © 2011-2022 走看看