zoukankan      html  css  js  c++  java
  • [APIO2012]派遣 dispatching

    左偏树。
    从下往上求每个子树的战斗力最大值。如果付出的薪水大于m,那么就pop了子树中最贵的那个点,把所有的子树合并起来,用左偏树维护。
    (好像所有的master都是1号点....)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=100005;
    int ch[N][2],val[N],fa[N],dis[N],lead[N],head[N],ecnt;
    int merge(int x,int y) {
    	if(!x||!y) return x+y;
    	if(val[x]<val[y]) swap(x,y);
    	ch[x][1]=merge(ch[x][1],y);
    	fa[ch[x][1]]=x;
    	if(dis[ch[x][0]]<dis[ch[x][1]]) swap(ch[x][0],ch[x][1]);
    	dis[x]=dis[ch[x][0]]+1;
    	return x;
    }
    void pop(int &x) {x=merge(ch[x][0],ch[x][1]);return;}
    struct Edge{int to,nxt;}e[N];
    void add(int bg,int ed){e[++ecnt].nxt=head[bg];e[ecnt].to=ed;head[bg]=ecnt;}
    int n,m,master,siz[N],belong[N];
    long long ans,sumcost[N];
    void dfs(int x) {
    	siz[x]=1;sumcost[x]=val[x];belong[x]=x;
    	for(int i=head[x];i;i=e[i].nxt) {
    		int v=e[i].to;
    		dfs(v);
    		belong[x]=merge(belong[v],belong[x]);
    		siz[x]+=siz[v];
    		sumcost[x]+=sumcost[v];
    		while(sumcost[x]>m&&siz[x]) sumcost[x]-=val[belong[x]],siz[x]--,pop(belong[x]);
    	}
    	ans=max(ans,lead[x]*1ll*siz[x]*1ll);
    }
    main() {
    	scanf("%lld%lld",&n,&m);
    	int a;
    	for(int i=1;i<=n;i++) {
    		scanf("%d%d%d",&a,&val[i],&lead[i]);
    		if(!a) master=i;
    		else {add(a,i);}
    	}
    	dfs(master);
    	cout<<ans;
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    数据攻略●R语言自述
    测试实例
    xml反射
    过滤器
    使用s标签来进行简单的表格配置
    将Spring、Hibernate、Struts2连接起来
    Spring容器
    初见Spring框架
    Spring框架的AOP
    Hibernate里面的几个方法
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9351117.html
Copyright © 2011-2022 走看看