首页 > 其他分享 >【题解 P1552】 派遣

【题解 P1552】 派遣

时间:2023-11-15 20:12:12浏览次数:30  
标签:忍者 le 题解 long 100005 P1552 派遣 节点

[APIO2012] 派遣

题目背景

在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。

题目描述

在这个帮派里,有一名忍者被称之为 Master。除了 Master 以外,每名忍者都有且仅有一个上级。为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送。

现在你要招募一批忍者,并把它们派遣给顾客。你需要为每个被派遣的忍者支付一定的薪水,同时使得支付的薪水总额不超过你的预算。另外,为了发送指令,你需要选择一名忍者作为管理者,要求这个管理者可以向所有被派遣的忍者发送指令,在发送指令时,任何忍者(不管是否被派遣)都可以作为消息的传递人。管理者自己可以被派遣,也可以不被派遣。当然,如果管理者没有被排遣,你就不需要支付管理者的薪水。

你的目标是在预算内使顾客的满意度最大。这里定义顾客的满意度为派遣的忍者总数乘以管理者的领导力水平,其中每个忍者的领导力水平也是一定的。

写一个程序,给定每一个忍者 \(i\) 的上级 \(B_i\),薪水 \(C_i\),领导力 \(L_i\),以及支付给忍者们的薪水总预算 \(M\),输出在预算内满足上述要求时顾客满意度的最大值。

输入格式

第一行包含两个整数 \(N\) 和 \(M\),其中 \(N\) 表示忍者的个数,\(M\)表示薪水的总预算。

接下来 \(N\) 行描述忍者们的上级、薪水以及领导力。其中的第i行包含三个整数 \(B_i,C_i,L_i\) 分别表示第 \(i\) 个忍者的上级,薪水以及领导力。Master 满足 \(B_i=0\),并且每一个忍者的老板的编号一定小于自己的编号 \(B_i\lt i\)。

输出格式

一行一个整数,表示在预算内顾客的满意度的最大值。

样例 #1

样例输入 #1

5 4
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1

样例输出 #1

6

提示

\(1 \le N \le 10^5\),\(1 \le M \le 10^9\),\(0 \le B_i \lt i\),\(1 \le C_i \le M\),\(1 \le L_i \le 10^9\)。

对于 \(30\%\) 的数据,\(N \le 3000\)。

解题思路

简单来说,就是找出一些总代价小于 \(m\) 的树上节点,使得他们的数量乘上他们的 \(LCA\) 的价值最大。
很明显,对于一个节点,若将它作为 \(LCA\) ,那么要选出最多的节点,要使每一个节点的代价尽可能的小。
所以我们需要求出一个子树内最多能选出多少个总共代价和小于 \(m\) 的节点。
那这就可以用可并堆了。
我们将每一个节点开始时都看做一个堆,一开始一共 \(n\) 个堆,每次向上合并时都将儿子节点的堆合并到自己的堆里面。
每次合并完后将堆里面最大的节点给去掉,直到堆代价和小于 \(m\) 为止,因为这样做是可以保证选出来尽量多的数。
每次删完后,取堆里节点个数乘上该节点的价值的最大值即可。
时间复杂度 \(O(nlogn)\) 。

Code

#include<bits/stdc++.h>
using namespace std;
long long n,m,d[100005],v[100005],root,s,size[100005],sum[100005];
long long f[100005],lc[100005],rc[100005],dist[100005];
vector<long long> a[100005]; 
long long dijah(long long x)
{
	if(f[x]!=x)f[x]=dijah(f[x]);
	return f[x];
}
long long merge(long long x,long long y)
{
	if(x==0)return y;
	if(y==0)return x;
	if(v[x]<v[y])swap(x,y);
	rc[x]=merge(rc[x],y);
	f[rc[x]]=x;
	if(dist[lc[x]]<dist[rc[x]])swap(lc[x],rc[x]);
	if(rc[x]!=0)dist[x]=dist[rc[x]]+1;
	else dist[x]=0;
	return x; 
}
void dfs(long long x,long long y)
{
	long long q,w;
	size[x]=1;
	sum[x]=v[x];
	for(int i=0;i<a[x].size();i++)
	{
		if(a[x][i]==y)continue;
		dfs(a[x][i],x);
		q=dijah(x);
		w=dijah(a[x][i]);
		size[q]=size[w]=size[q]+size[w];
		sum[q]=sum[w]=sum[q]+sum[w];
		f[q]=f[w]=merge(q,w);
	}
	while(sum[dijah(x)]>m)
	{
		q=dijah(x);
		size[lc[q]]=size[rc[q]]=size[q]-1;
		sum[lc[q]]=sum[rc[q]]=sum[q]-v[q];
		f[lc[q]]=f[rc[q]]=merge(lc[q],rc[q]);
		f[q]=lc[q];
	} 
	s=max(s,size[dijah(x)]*d[x]);
	return;
}
int main()
{
	dist[0]=-1;
	long long x;
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++)f[i]=i;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld%lld",&x,&v[i],&d[i]);
		if(x!=0)a[x].push_back(i),a[i].push_back(x);
		else root=i;
	}
	dfs(root,0);
	cout<<s;








  return 0;
}

标签:忍者,le,题解,long,100005,P1552,派遣,节点
From: https://www.cnblogs.com/dijah/p/17834658.html

相关文章

  • 题解 P7405 [JOI 2021 Final] 雪玉
    洛谷。题意应该好理解的。分析我们的所有雪球在同一时间之间的距离都是相同的,因此一段雪,要么是它左侧的第一个所取,要么右侧第一个所取,要么不被取,并且,我们每一个雪球所占有的雪是连续的一段。我们令\(L_i\)表示第\(i\)步前所能走的最左点,\(R_i\)表示第\(i\)步前所能走......
  • Q7.4.1.3. 产品销售 题解
    原题链接连\(S\toA_i\),流量\(D_i\),费用\(P_i\),表示最多进货\(D_i\),成本为\(P_i\)。连\(A_i\toT\),流量\(U_i\),费用\(0\),表示卖出。连\(A_i\toA_{i+1}\),流量\(+\infty\),费用\(C_i\),表示把\(A_i\)的货物拖一天花费\(C_i\)。连\(A_{i+1}\toA_i\),流量\(+\inft......
  • [题解]AT_abc267_f [ABC267F] Exactly K Steps
    大家好,我是毒瘤,喜欢用玄学算法过题。发现题解区没有这个做法,于是来发一篇。思路不难发现如果一个点对\((u,v)\)的距离为\(d\),那么在这棵树以\(u\)为根时,\(v\)的深度为\(d\)。于是考虑换根DP。首先思考如何计算答案。显然我们可以将查询离线下来,然后当换根到以\(u\)......
  • 题解 「2019五校联考-镇海1」一棵树
    题意一棵\(n\)个结点的树,根节点为\(1\),结点\(i\)的父亲是\(f_i\)。\(f_1=f_0=0\)。对于每一个整数\(i\),假如\(f_{f_i}\)不为\(0\),那么就将\(f_{f_i}\)与\(i\)连上一条边。从每一个结点,每次随机向相邻的结点走。问每个结点期望走多少步才能走到根。对于\(60\%\),\(......
  • bupt ai院第一次周赛题解
    题目一简单模拟题点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineebkemplace_back#definexfirst#defineysecondtypedefpair<int,int>PII;typedeflonglongll;typedefunsignedlonglongull;typedefvector<string>VS;typedef......
  • subject organization is not system:nodes 问题解决
    在下面的issues找到了答案:https://github.com/kubernetes/kubernetes/issues/99504┌──[[email protected]]-[~]└─$kubectlgetcsrNAMEAGESIGNERNAMEREQUESTORREQU......
  • 【课程】算法设计与分析——第八周 题解笔记
    第八周算法题解笔记1极值点题目描述给定一个单峰函数f(x)和它的定义域,求它的极值点该单峰函数f(x)保证定义域内有且只有一个极值点,且为极大值点题解本题感觉和dp关系不大,主要思路是三分法,和二分法非常类似,但没有二分法常用,主要用途是用来求单峰函数的极值对于任意一个......
  • [ARC107F] Sum of Abs 题解
    题意给定一个\(N\)个点,\(M\)条边的简单无向图,每个节点有两个值\(A_i\)和\(B_i\)。现对于每个节点,均可以选择花费\(A_i\)的代价将其删去或保留节点。若一个节点被删除,那么所有与其向连的边也会被删除。定义一个极大联通块的权值为联通块内所有节点的\(B_i\)的和的绝对......
  • 电脑网站支付报错“验签出错,建议检查签名字符串或私钥与应用公钥是否匹配”问题解决记
    在对接支付宝电脑网站支付的时候,遇到如下报错:“错误代码invalid-signature错误原因:验签出错,建议检查签名字符串或签名私钥与应用公钥是否匹配”。但展示的报错内容跟实际原因有所出入(在下文中有解答),这里记录下问题的解决排查过程。 问题复现在对接电脑网站支付时,生成......
  • 【洛谷 P1089】[NOIP2004 提高组] 津津的储蓄计划 题解(循环)
    [NOIP2004提高组]津津的储蓄计划题目描述津津的零花钱一直都是自己管理。每个月的月初妈妈给津津元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上还给津津。因此津津制定了一......