[APIO2012] Dispatch

[APIO2012] Dispatch

Topic description

  In this gang, there is a ninja called Master. Except for the Master, every ninja has one and only one superior. In order to maintain secrecy and enhance the leadership of the ninjas, all instructions related to their work are always sent by the superior to his direct subordinates, and are not allowed to be sent by other means.

  Now you're going to recruit a group of ninjas and dispatch them to customers. You need to pay a certain amount of salary for each ninja dispatched, while keeping the total salary paid within your budget. In addition, in order to send commands, you need to select a ninja as a manager, and this manager is required to send commands to all dispatched ninjas. When sending commands, any ninja (whether dispatched or not) can be used as a message transmitter . Managers themselves may or may not be dispatched. Of course, if the manager is not dismissed, you don't need to pay the manager.

  Your goal is to maximize customer satisfaction within your budget. Here, customer satisfaction is defined as the total number of dispatched ninjas multiplied by the manager's leadership level, where the leadership level of each ninja is also certain.

  Write a program that, given each ninja i's superior Bi, salary Ci, leadership Li, and the total salary budget M paid to the ninjas, output the maximum value of customer satisfaction when the above requirements are met within the budget.

Input and output format

Input format: 

  The first line contains two integers N and M, where N is the number of ninjas and M is the total salary budget.

  The next N lines describe the ninja's superiors, salary, and leadership. The i-th row contains three integers Bi, Ci, and Li, which represent the i-th ninja's superior, salary, and leadership, respectively. Master satisfies Bi=0, and the number of each ninja's boss must be less than his own number Bi<i. 

Output format:

  Output a number that represents the maximum customer satisfaction within the budget.

Input and output example

Input sample:
5 4
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1
Sample output:
6

ideas

  This question is more obvious and can be stacked together. First, let's read the question. The title says that we require the greatest satisfaction value. First of all, let's analyze that when a designated ninja is the master, his ability value is certain. If you want to be the largest, the number of ninjas must be the largest. Then we have to choose the ninja with the least salary to perform the task. If the analysis At this point, the problem becomes much brighter. We can maintain a mergeable large root heap, and while maintaining this heap, maintain the salary sum of all ninjas in the heap and the number of ninjas. If the salary sum is greater than the budget value, pop the largest value (heap top element), you can Now, since the relationship satisfies a tree, we can maintain it from bottom to top. Isn't it simpler?

code

#include <stdio.h>
int n,m;
int val[100001];
int cost[100001];
int head[100001];
int to[100001];
int nxt[100001];
int dis[100001];
int many[100001];
int lson[100001];
int rson[100001];
long long sum[100001];
int idx,root;
long long ans;
long long max(long long a,long long b)
{
    return (a<b)?b:a;
}
void swap(int &a,int &b)
{
    a+=b,b=a-b,a-=b;
}
void add(int x,int y)
{
    nxt[++idx]=head[x];
    head[x]=idx;
    to[idx]=y;
}
int merge(int x,int y)
{
    if(!x) return y;
    if(!y) return x;
    if(cost[x]<cost[y]) swap(x,y);
    rson[x]=merge(rson[x],y);
    if(dis[rson[x]]>dis[lson[x]])
        swap(rson[x],lson[x]);
    dis [x] = dis [rson [x]] + 1;
    sum[x]=cost[x]+sum[lson[x]]+sum[rson[x]];
    many[x]=many[rson[x]]+many[lson[x]]+1;
    return x;
}
int check(int p)
{
    while(sum[p]>m)
    {
        long long tmp=sum[p]-cost[p];
        int tmp2=many[p];
        p=merge(lson[p],rson[p]);
        sum[p]=tmp,many[p]=tmp2-1;
    }
    return p;
}
int dfs(int p)
{
    int head1=p,tmp=0;
    for(int i=head[p];i;i=nxt[i])
        tmp=dfs(to[i]),head1=merge(head1,tmp);
    head1=check(head1);
    ans=max(ans,((long long)many[head1]*val[p]));
    return head1;
}
intmain()
{
    dis[0]=-1;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        int a;
        scanf("%d%d%d",&a,&cost[i],&val[i]);
        if(a) add(a,i);
        else root=i;
    }
    for(int i=1;i<=n;i++)
        many[i]=1,sum[i]=cost[i];
    dfs(root);
    printf("%lld\n",ans);
}

  If there is something you don't understand, you can leave a comment and I will answer

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324774946&siteId=291194637