ZOJ 3910 Market ZOJ Monthly, October 2015 - H

Market

Time Limit: 2 Seconds      Memory Limit: 65536 KB

There's a fruit market in Byteland. The salesmen there only sell apples.

There are n salesmen in the fruit market and the i-th salesman will sell at most wi apples. Every salesman has an immediate manager pi except one salesman who is the boss of the market. A salesman A is said to be the superior of another salesman B if at least one of the followings is true:

 

  • Salesman A is the immediate manager of salesman B.
  • Salesman B has an immediate manager salesman C such that salesman A is the superior of salesman C.

 

The market will not have a managerial cycle. That is, there will not exist a salesman who is the superior of his/her own immediate manager.

We will call salesman x a subordinate of another salesman y, if either y is an immediate manager of x, or the immediate manager of x is a subordinate to salesman y. In particular, subordinates of the boss are all other salesmen of the market. Let the degree of the boss be 0. Then if the degree of i-th salesman is k, the immediate subordinates of i-th salesman will have degree k + 1.

Today, m buyers come to market for apples. The i-th buyer will buy at most ci apples only from the xi-th salesman and his subordinates whose degree is no larger than xi-th salesman's degree plus di.

The boss wants to know how many apples can be sold in salesmen's best effort (i.e. the maximum number).

Input

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains two integers n and m (1 ≤ nm ≤ 10000) — the number of salesmen and the number of buyers.

The second line contains n integers w1w2, ..., wn (1 ≤ wi ≤ 105). Every wi denotes the number of apples that i-th salesman can sell.

The next line contains n integers pi (1 ≤ pi ≤ n or pi = -1). Every pi denotes the immediate manager for the i-th salesman. If pi is -1, that means that the i-th salesman does not have an immediate manager.

Each of the next m lines contains three integers cixi and di (1 ≤ ci ≤ 105, 1 ≤ xi ≤ n, 0 ≤ di ≤ n) — the information of i-th buyer.

It is guaranteed that the total number of salesmen in the input doesn't exceed 105, and the total number of buyers also doesn't exceed 105. The number of test cases in the input doesn't exceed 500.

Output

For each test case, output a single integer denoting the maximum number of apples can be sold.

Sample Input

1
4 2
1 2 3 4
-1 1 2 3
3 2 1
5 1 1

Sample Output

6

Author: LIN, Xi

 

题意:给出一棵n个点的树,然后每个点有个权值,给出m次操作,每次操作让你从第i个点以及其下面d层的所有点中   最多减去c的权值(可以分开减),问最后最多划去多少权值?

分析:这题明显就是贪心,想啊想啊就容易想到平衡术合并维护,贪心优先划掉层数较大的权值

就是每个点都有一个平衡树,代表这个点为根的子树已经处理完下面的操作了之后,所有有权值的点,

然后把这个平衡树向上启发式合并

整个过程是从下往上的

c++可以使用set做这题,pascal就悲剧了。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <deque>
  6 #include <vector>
  7 #include <queue>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <map>
 11 #include <set>
 12 #include <ctime>
 13 using namespace std;
 14 typedef long long LL;
 15 typedef double DB;
 16 #define For(i, s, t) for(int i = (s); i <= (t); i++)
 17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--)
 18 #define Rep(i, t) for(int i = (0); i < (t); i++)
 19 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--)
 20 #define rep(i, x, t) for(int i = (x); i < (t); i++)
 21 #define MIT (2147483647)
 22 #define INF (1000000001)
 23 #define MLL (1000000000000000001LL)
 24 #define sz(x) ((int) (x).size())
 25 #define clr(x, y) memset(x, y, sizeof(x))
 26 #define puf push_front
 27 #define pub push_back
 28 #define pof pop_front
 29 #define pob pop_back
 30 #define ft first
 31 #define sd second
 32 #define mk make_pair
 33 inline void SetIO(string Name) {
 34     string Input = Name+".in",
 35     Output = Name+".out";
 36     freopen(Input.c_str(), "r", stdin),
 37     freopen(Output.c_str(), "w", stdout);
 38 }
 39 
 40 inline int Getint() {
 41     int Ret = 0;
 42     bool Flag = 0;
 43     char Ch = ' ';
 44     while(!(Ch >= '0' && Ch <= '9')) {
 45         if(Ch == '-') Flag ^= 1;
 46         Ch = getchar();
 47     }
 48     while(Ch >= '0' && Ch <= '9') {
 49         Ret = Ret*10+Ch-'0';
 50         Ch = getchar();
 51     }
 52     return Flag ? -Ret : Ret;
 53 }
 54 
 55 const int N = 10010;
 56 int n, m, Arr[N];
 57 int Fa[N], First[N], To[N], Next[N], Tot;
 58 int Root, Que[N], Degree[N], Ans;
 59 typedef pair<int, int> II;
 60 vector<II> Salesman[N];
 61 set<II> Splay[N];
 62 int Set[N];
 63 
 64 inline void Insert(int u, int v) {
 65     Tot++;
 66     To[Tot] = v, Next[Tot] = First[u];
 67     First[u] = Tot;
 68 }
 69 
 70 inline void Init() {
 71     For(i, 1, n) {
 72         Splay[i].clear(), Salesman[i].clear();
 73         Set[i] = i, First[i] = 0;
 74     }
 75     Tot = 0;
 76 }
 77 
 78 inline void Solve();
 79 
 80 inline void Input() {
 81     int Test;
 82     //scanf("%d", &Test);
 83     Test = Getint();
 84     while(Test--) {
 85         //scanf("%d%d", &n, &m);
 86         n = Getint();
 87         m = Getint();
 88         For(i, 1, n) Arr[i] = Getint();
 89         
 90         Init();
 91         
 92         Tot = 0;
 93         For(i, 1, n) {
 94             Fa[i] = Getint();
 95             if(Fa[i] != -1) Insert(Fa[i], i);
 96             else Root = i;
 97         }
 98         
 99         For(i, 1, m) {
100             int C, x, D;
101             C = Getint();
102             x = Getint();
103             D = Getint();
104             Salesman[x].pub(mk(C, D));
105         }
106         
107         Solve();
108     }
109 }
110 
111 inline void Bfs(int Start) {
112     static int Head, Tail;
113     Head = Tail = 1, Que[1] = Start, Degree[Start] = 0;
114     while(Head <= Tail) {
115         int u = Que[Head++];
116         for(int Tab = First[u], v; Tab; Tab = Next[Tab]) {
117             v = To[Tab];
118             Degree[v] = Degree[u]+1, Que[++Tail] = v;
119         }
120     }
121 }
122 
123 inline void Merge(int x, int y) {
124     for(set<II>::iterator It = Splay[Set[y]].begin(); It != Splay[Set[y]].end(); It++)
125         Splay[Set[x]].insert(*It);
126 }
127 
128 inline int Work(int x) {
129     int Ret = 0;
130     Splay[Set[x]].insert(mk(Degree[x], x));
131 
132     int Len = sz(Salesman[x]), Size = sz(Splay[Set[x]]);
133     set<II>::iterator It;
134     Rep(i, Len) {
135         int Buy = Salesman[x][i].ft, D = Salesman[x][i].sd, T;
136         while(Buy && Size) {
137             It = Splay[Set[x]].upper_bound(mk(Degree[x]+D, INF));
138             if(It == Splay[Set[x]].begin()) break;
139             It--;
140             T = min(Arr[It->sd], Buy);
141             Arr[It->sd] -= T, Buy -= T;
142             if(Arr[It->sd] == 0) {
143                 Splay[Set[x]].erase(It);
144                 Size--;
145             }
146         }
147         Ret += Salesman[x][i].ft-Buy;
148     }
149     
150     if(Fa[x] != -1) {
151         Size = sz(Splay[Set[x]]);
152         int FaSize = sz(Splay[Set[Fa[x]]]);
153         if(FaSize < Size) swap(Set[x], Set[Fa[x]]);
154         Merge(Fa[x], x);
155     }
156     
157     return Ret;
158 }
159 
160 inline void Solve() {
161     Bfs(Root);
162     
163     Ans = 0;
164     Ford(i, n, 1)
165         Ans += Work(Que[i]);
166     
167     printf("%d\n", Ans);
168 }
169 
170 int main() {
171     SetIO("H");
172     Input();
173     //Solve();
174     return 0;
175 }
View Code

 

posted @ 2015-10-16 19:42  yanzx6  阅读(201)  评论(0编辑  收藏  举报