您的位置:首页 > 其它

可并堆-bzoj2809: [Apio2012]dispatching

2017-03-02 11:16 357 查看
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 long
using 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
4000
-=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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: