796. [APIO2012] Dispatch
"Problem description"
in a ninja gang, some ninjas are selected to be dispatched to the customer and rewarded for their work.
in this gang, a ninja is called Master. In addition to master, each ninja has and has only one parent. To keep it private and to enhance the leadership of the Ninja, all instructions related to their work are always sent by the superior to his direct subordinates, and not by other means.
Now you need to recruit a bunch of ninjas and send them to customers. You need to pay a certain salary for each ninja you send, and make the total amount you pay not exceed your budget. In addition, in order to send instructions, you need to select a ninja as the manager, ask the manager to send instructions to all the sent ninja, when sending instructions, any ninja (whether or not dispatched) can be the message of the sender. Managers themselves can be dispatched, or they may not be dispatched. Of course, you don't need to pay a manager's salary if the manager is not being taken.
your goal is to make the most of your customers ' satisfaction on budget. This defines the customer's satisfaction as the total number of ninjas dispatched is multiplied by the manager's leadership level, and each ninja's leadership level is also certain.
Write a program that gives the top bi of each ninja I, salary ci, leadership Li, and the total salary of the ninja to pay the total budget m, outputting the maximum customer satisfaction when the budget meets the above requirements.
"Data Range"
The number of 1≤n≤100,000 ninjas;
1≤m≤1,000,000,000 salary total budget;
0≤bi < I ninja's superior number;
1≤ci≤m Ninja's salary;
1≤li≤1,000,000,000 Ninja's leadership level.
For 30% of data, n≤3000.
"Input Format"
Reads data from standard input.
The first line contains two integers n and M, where n represents the number of ninjas, and M represents the total budget for the salary.
The next n lines describe the Ninja's superiors, their salary, and their leadership. The line I contains three integer bi, Ci, and Li, respectively, representing the ancestors of the ninja, salary and leadership. Master Meets bi = 0, and each ninja's boss's number must be smaller than its own number bi < I.
"Output Format"
Output to standard output.
Outputs a number that represents the maximum value of customer satisfaction in the budget.
"Sample Input"
5 4
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1
"Sample Output"
6
"Sample description"
If we choose a ninja numbered 1 as a manager and dispatch a third and fourth Ninja, the sum of the salaries is 4, not exceeding the total budget of 4. Because 2 ninjas were dispatched and the manager's leadership was 3, the user's satisfaction was 2x3 = 6, which was the maximum number of user satisfaction that could be obtained.
A the first left-leaning tree of the question, spent a long time.
Greed is obvious, if there is a smaller wage ninja is not selected, obviously elected him better, but, when it should be done in reverse! ① just need to maintain a large heap. If it is larger than M, keep the big root pop-up. It is difficult to think in reverse! Must pay attention to strengthen the use.
As a result, I have maintained two heaps of SB. Also maintains the mapping of each element in the small root heap, and then I need to delete the non-root node in the small root heap. Then I'll be hehe.
Wrote for a long time to write, found that ② to delete the non-root node need to maintain the parent pointer, and change the merge function, the merge function in the first maintenance of a, B's parent pointer, first delete the node's father pointer to its child, merge the left and right of the deleted node subtree, and then merge it with the original tree. . It is also a bit of a harvest, at least to study how to delete the non-root node, and does not seem so simple.
③ Set Empty node, this thing must have, too steward! At first, because there is no empty node, the egg hurts for a long time or fry; the result is correct.
④ there is a type! I started using%d to output a long long!
But.. Said so much, the first reflection should also be the idea, there is no need for small Gan!
This is the original code:
#include <iostream>using namespace std #include <cstdio> #include <cstring> #include <algorithm > #include <cmath> #include <cstdlib>char * ptr= (char *) malloc (5000000), inline void in (int. &x) {while ( *ptr< ' 0 ' | | *ptr> ' 9 ') ++ptr;x=0;while (*ptr>47&&*ptr<58) x=x*10+*ptr++-' 0 ';} #define MAXN 100001#include<vector>vector<int> Son[maxn];int sum[maxn],num[maxn],b[maxn],c[maxn],l[ Maxn];struct Ls{ls * f,* c[2];int key,x,distance;} *null=new LS ((LS) {null,null,null,0,0,-1}), *ROOT[MAXN][2],*POINT[MAXN]; ls * Merge (LS * a,ls * b,ls * f,bool flag) {//cout<< "M:" <<A->x<< "(" <<A->key<< ")" < < "<<B->x<<" ("<<B->key<<") <<endl; a->f=f; B->f=f;if (a->c[1]==a) {cout<<a->x<< "" <<b->x<<endl;} if (a==null) return b;if (B==null) return a;if (flag? A->key<b->key:a->key>b->key) Swap (A, b); A->c[1]=merge (A->c[1],b,a,flag); if (A->c[0]->distance<a->c[1]->distance) Swap (a->c[0],a->c[1]); A->distance=a->c[1]->distance+1;return A;} int main () {freopen ("dispatching.in", "R", stdin), Freopen ("Dispatching.out", "w", stdout); Fread (Ptr,1,5000000,stdin) ; int N,w;in (N), in (W); in (B[1]), in (C[1]), in (l[1]), int i,j;for (i=2;i<=n;++i) {in (B[i]), in (C[i]), in (L[i]); Son[b[i] ].push_back (i);} Long Long ans=0; LS * TMP;FOR (i=n;i;--i) {if (c[i]<=w) {root[i][0]=new ls (ls) {null,null,null,c[i],i,0}); root[i][1]=new ls ((LS) { null,null,null,c[i],i,0}); sum[i]=c[i],num[i]=1;point[i]=root[i][0];} Else{root[i][0]=null;root[i][1]=null;} For (J=son[i].size (); j--;) {root[i][0]=merge (root[i][0],root[son[i][j]][0],null,0); Root[i][1]=merge (Root[i][1], root[son[i][j]][1],null,1); Sum[i]+=sum[son[i][j]];num[i]+=num[son[i][j]];while (Sum[i]>W) {sum[i]-=root[i][1] ->key;--num[i];tmp=point[root[i][1]->x];if (tmp->f==null) Root[root[i][1]->x][0]=merge (Tmp->c[0], tmp->c[1],null,0); Else{if (tmp->f->c[0]==tmp) Tmp->f->c[0]=null;else tmp->f->c[1]=null;root[i][0]=merge (Root[i][0],merge (tmp->c[0],tmp->c[1],null,0), null,0);} Root[i][1]=merge (root[i][1]->c[0],root[i][1]->c[1],null,1);}} Ans=max (ans, (long Long) l[i]*num[i]);} Cout<<ans;}
Read someone else's code after the change:
#include <iostream>using namespace std #include <cstdio> #include <cstring> #include <algorithm > #include <cmath> #include <cstdlib>char * ptr= (char *) malloc (5000000), inline void in (int. &x) {while ( *ptr< ' 0 ' | | *ptr> ' 9 ') ++ptr;x=0;while (*ptr>47&&*ptr<58) x=x*10+*ptr++-' 0 ';} #define MAXN 100001#include<vector>vector<int> Son[maxn];int sum[maxn],num[maxn],b[maxn],c[maxn],l[ Maxn];struct Ls{ls * C[2];int key,x,distance;} *null=new LS ((LS) {null,null,0,0,-1}), *ROOT[MAXN]; ls * Merge (LS * a,ls * B) {if (a==null) return b;if (B==null) return a;if (A->key<b->key) swap (A, b); A->c[1]=merge (a->c[1],b); if (a->c[0]->distance<a->c[1]->distance) swap (A->c[0],A->c[1 ]); A->distance=a->c[1]->distance+1;return A;} int main () {freopen ("dispatching.in", "R", stdin), Freopen ("Dispatching.out", "w", stdout); Fread (Ptr,1,5000000,stdin) ; int N,w;in (N), in (W); in (B[1]), in (C[1]), in (l[1]), int i,j;for (i=2;i<=n;++i) {in (B[i]), in (C[i]), in (l[I]); Son[b[i]].push_back (i);} Long Long ans=0;for (i=n;i;--i) {if (c[i]<=w) {root[i]=new ls (ls) {null,null,c[i],i}); sum[i]=c[i],num[i]=1;} Else Root[i]=null;for (J=son[i].size (); j--;) {root[i]=merge (root[i],root[son[i][j]]); sum[i]+=sum[son[i][j]];num[i ]+=num[son[i][j]];while (sum[i]>w) {Sum[i]-=root[i]->key;--num[i];root[i]=merge (root[i]->c[0],root[i]- >C[1]);}} Ans=max (ans, (long Long) l[i]*num[i]);} Cout<<ans;}
[APIO2012] Dispatch Problem solving report