这题的话题意有点点难懂(可能是我太弱了。。),大概就是说给你一颗树,你可以在上面选一些点(他们的薪水总和给得起),然后你要找一个他们的公共祖先a,是的a的管理能力乘上他们的人数最大
怎么做呢?其实很简单
我们就dfs一次树,大概就是枚举这个公共祖先是谁
然后我们理所当然地是从要钱少的开始拿
这样就需要将儿子们的字数信息合并了
我们维护一个大根堆,然后要是多了,就删人。。
大概就这样
#include<cstdio>
#include<cstring>
typedef
long
long
LL;
#define swap(x,y) {LL tt=x;x=y;y=tt;}
const
LL N=100005;
LL n,m;
LL b[N],c[N];
//薪水 领导力
struct
qq{LL x,y,last;}e[N];
LL num,last[N];
void
init (LL x,LL y)
{
num++;
e[num].x=x;e[num].y=y;
e[num].last=last[x];
last[x]=num;
}
LL d[N],l[N],r[N];
LL root[N],cnt;
LL v[N];
LL lalal[N];
//有多少人
LL ooo[N];
//这一棵子树v值的和
LL Merge (LL x,LL y)
{
if
(x==0||y==0)
return
x+y;
if
(v[x]<v[y]) swap(x,y);
//我要维护大根堆
r[x]=Merge(r[x],y);
lalal[x]=lalal[l[x]]+lalal[r[x]]+1;
ooo[x]=v[x]+ooo[l[x]]+ooo[r[x]];
if
(d[r[x]]>d[l[x]]) swap(l[x],r[x]);
d[x]=d[r[x]]+1;
return
x;
}
LL mymax (LL x,LL y){
return
x>y?x:y;}
LL ans=0;
void
dfs (LL x)
{
root[x]=++cnt;
ooo[cnt]=v[cnt]=b[x];
d[cnt]=0;
lalal[cnt]=1;
for
(LL u=last[x];u!=-1;u=e[u].last)
{
LL y=e[u].y;
dfs(y);
root[x]=Merge(root[x],root[y]);
}
while
(ooo[root[x]]>m) root[x]=Merge(l[root[x]],r[root[x]]);
ans=mymax(ans,c[x]*lalal[root[x]]);
}
int
main()
{
d[0]=-1;
num=0;
memset
(last,-1,
sizeof
(last));
scanf
(
"%lld%lld"
,&n,&m);
for
(LL u=1;u<=n;u++)
{
LL x;
scanf
(
"%lld%lld%lld"
,&x,&b[u],&c[u]);
init(x,u);
}
dfs(1);
printf
(
"%lld\n"
,ans);
return
0;
}
#include<cstdio>
#include<cstring>
typedef
long
long
LL;
#define swap(x,y) {LL tt=x;x=y;y=tt;}
const
LL N=100005;
LL n,m;
LL b[N],c[N];
//薪水 领导力
struct
qq{LL x,y,last;}e[N];
LL num,last[N];
void
init (LL x,LL y)
{
num++;
e[num].x=x;e[num].y=y;
e[num].last=last[x];
last[x]=num;
}
LL d[N],l[N],r[N];
LL root[N],cnt;
LL v[N];
LL lalal[N];
//有多少人
LL ooo[N];
//这一棵子树v值的和
LL Merge (LL x,LL y)
{
if
(x==0||y==0)
return
x+y;
if
(v[x]<v[y]) swap(x,y);
//我要维护大根堆
r[x]=Merge(r[x],y);
lalal[x]=lalal[l[x]]+lalal[r[x]]+1;
ooo[x]=v[x]+ooo[l[x]]+ooo[r[x]];
if
(d[r[x]]>d[l[x]]) swap(l[x],r[x]);
d[x]=d[r[x]]+1;
return
x;
}
LL mymax (LL x,LL y){
return
x>y?x:y;}
LL ans=0;
void
dfs (LL x)
{
root[x]=++cnt;
ooo[cnt]=v[cnt]=b[x];
d[cnt]=0;
lalal[cnt]=1;
for
(LL u=last[x];u!=-1;u=e[u].last)
{
LL y=e[u].y;
dfs(y);
root[x]=Merge(root[x],root[y]);
}
while
(ooo[root[x]]>m) root[x]=Merge(l[root[x]],r[root[x]]);
ans=mymax(ans,c[x]*lalal[root[x]]);
}
int
main()
{
d[0]=-1;
num=0;
memset
(last,-1,
sizeof
(last));
scanf
(
"%lld%lld"
,&n,&m);
for
(LL u=1;u<=n;u++)
{
LL x;
scanf
(
"%lld%lld%lld"
,&x,&b[u],&c[u]);
init(x,u);
}
dfs(1);
printf
(
"%lld\n"
,ans);
return
0;
}