可并堆-bzoj2809: [Apio2012]dispatching

来源:互联网 发布:erp软件排名 编辑:程序博客网 时间:2024/05/17 04:33

http://www.lydsy.com/JudgeOnline/problem.php?id=2809
本来1A的,结果,ll没开全;
首先题目看懂,这个题目不长,但是要看懂;
看懂之后就会发现整个结构是树型的;
然后我们就可以搞事了呀;
和树形dp很像的;
我们维护n个大根堆;
不断把子节点合并到跟节点;
合并完了就不断弹出堆顶,就是工资最大的数;
直到当前堆里面全部工资小于等于m;
更新答案;
注意的是这里的一个堆,里面的参数的指向不清晰;
模版题目的指向是很清晰的;
这个就要严谨的逻辑关系;

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define Ll long longusing namespace std;struct cs{    int to,next;}a[100000];struct heap{    Ll xx,yy,vv,money,num,fa;//vv是领导值,num堆内是有几个点,sum是总工资     Ll sum;}q[100001];int head[100001];Ll n,m,x,y,z,ll,S;Ll ans;void init(int x,int y){    a[++ll].to=y;    a[ll].next=head[x];    head[x]=ll;}int merge(int x,int y){    if(!x)return y;    if(!y)return x;    if(q[x].money<q[y].money)swap(x,y);    q[x].yy=merge(q[x].yy,y);    swap(q[x].xx,q[x].yy);    return x;}void del(int x){//弹出堆顶     int xx=q[x].fa;    q[x].num--;    q[x].sum-=q[xx].money;    q[x].fa=merge(q[xx].xx,q[xx].yy);}void dfs(int x){    for(int k=head[x];k;k=a[k].next){        dfs(a[k].to);        q[x].num+=q[a[k].to].num;        q[x].sum+=q[a[k].to].sum;        q[x].fa=merge(q[x].fa,q[a[k].to].fa);    }    while(q[x].sum>m)del(x);    ans=max(ans,q[x].vv*q[x].num);}int main(){    scanf("%lld%lld",&n,&m);    for(int i=1;i<=n;i++){        scanf("%lld%lld%lld",&x,&y,&z);        q[i].money=y;        q[i].sum=y;        q[i].num=1;        q[i].vv=z;        q[i].fa=i;        init(x,i);        if(!x)S=i;    }    dfs(S);    printf("%lld",ans);}
0 0
原创粉丝点击