您的位置:首页 > 其它

ZOJ 3910 Market

2015-10-13 11:54 197 查看
MarketTime 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 salesmanA 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 ≤ n, m ≤ 10000) — the number of salesmen and the number of buyers.

The second line contains n integers w1, w2, ..., 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 ci, xi 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
Source: ZOJ Monthly, October 2015

解题:网络流,关键是,由于点多,导致边更多,直接建图,爆内存。。。

感谢Claris的帮助,在花费了一两天的时间,终于搞定了

#include <bits/stdc++.h>
using namespace std;
const int N = 10010,M = 500000,INF = 0x3f3f3f3f;
int n,m;
struct arc{
int to,flow,next;
arc(int x = 0,int y = 0,int z = -1){
to = x;
flow = y;
next = z;
}
}e[3000000];
int cur[M],h[M],gap[M],head[M],S,T,tot;
void addedge(int u,int v,int flow){
if(!u || !v) return;
e[tot] = arc(v,flow,head[u]);
head[u] = tot++;
e[tot] = arc(u,0,head[v]);
head[v] = tot++;
}
int sap(int u,int low){
if(u == T) return low;
int ret = 0;
for(int &i = cur[u]; ~i; i = e[i].next){
if(e[i].flow && h[u] == h[e[i].to] + 1){
int a = sap(e[i].to,min(low,e[i].flow));
e[i].flow -= a;
e[i^1].flow += a;
low -= a;
ret += a;
if(!low) return ret;
}
}
if(!(--gap[h[u]])) h[S] = T;
gap[++h[u]]++;
cur[u] = head[u];
return ret;
}
namespace REDUCE {
int cnt,tot,leaf
,dep
,root
,l[M],r[M],head
;
int hd
,num;
struct arc {
int to,next;
arc(int x = 0,int y = -1) {
to = x;
next = y;
}
} e
;
struct QU {
int to,L,R,next;
QU(int to = 0,int L = 0,int R = 0,int nxt = -1) {
this->to = to;
this->L = L;
this->R = R;
this->next = nxt;
}
} Q
;
void add(int u,int v) {
e[tot] = arc(v,head[u]);
head[u] = tot++;
}
void addask(int u,int v,int L,int R) {
Q[num] = QU(v,L,R,hd[u]);
hd[u] = num++;
}
int merge(int x,int y,int L,int R) {
if(!x) return y;
if(!y) return x;
int z = ++cnt;
if(L == R) {
addedge(z,x,INF);
addedge(z,y,INF);
return z;
}
int mid = (L + R)>>1;
addedge(z,l[z] = merge(l[x],l[y],L,mid),INF);
addedge(z,r[z] = merge(r[x],r[y],mid + 1,R),INF);
return z;
}
int build(int L,int R,int pos) {
int x = ++cnt;
if(L == R) return x;
int mid = (L + R)>>1;
if(pos <= mid) addedge(x,l[x] = build(L,mid,pos),INF);
if(pos > mid) addedge(x,r[x] = build(mid+1,R,pos),INF);
return x;
}
void ask(int root,int L,int R,int lt,int rt,int node) {
if(!root) return;
if(lt <= L && rt >= R) {
addedge(node,root,INF);
return;
}
int mid = (L + R)>>1;
if(lt <= mid && l[root]) ask(l[root],L,mid,lt,rt,node);
if(rt > mid && r[root]) ask(r[root],mid + 1,R,lt,rt,node);
}
void dfs(int u,int depth) {
dep[u] = depth;
root[u] = build(1,n,dep[u]);
leaf[u] = cnt;
for(int i = head[u]; ~i; i = e[i].next)
dfs(e[i].to,depth + 1);
}
void dfs(int u) {
for(int i = head[u]; ~i; i = e[i].next) {
dfs(e[i].to);
root[u] = merge(root[u],root[e[i].to],1,n);
}
for(int i = hd[u]; ~i; i = Q[i].next)
ask(root[u],1,n,Q[i].L,min(n,Q[i].R),Q[i].to);
}
void init() {
memset(head,-1,sizeof head);
num = tot = cnt = 0;
memset(hd,-1,sizeof hd);
memset(l,0,sizeof l);
memset(r,0,sizeof r);
}
}
int have
,need
,hs
;
int main() {
int kase,u,v,w,rt;
scanf("%d",&kase);
memset(head,-1,sizeof head);
while(kase--) {
scanf("%d%d",&n,&m);

tot = 0;
REDUCE::init();
for(int i = 1; i <= n; ++i)
scanf("%d",have + i);
for(int i = 1; i <= n; ++i) {
scanf("%d",&u);
if(~u) REDUCE::add(u,i);
else rt = i;
}
REDUCE::dfs(rt,1);
for(int i = 1; i <= m; ++i) {
scanf("%d%d%d",need + i,&u,&v);
REDUCE::addask(u,hs[i] = ++REDUCE::cnt,REDUCE::dep[u],v + REDUCE::dep[u]);
}
REDUCE::dfs(rt);
S = ++REDUCE::cnt;
T = ++REDUCE::cnt;
for(int i = 1; i <= m; ++i)
addedge(S,hs[i],need[i]);
for(int i = 1; i <= n; ++i)
addedge(REDUCE::leaf[i],T,have[i]);
int maxflow = 0;
gap[0] = T;
while(h[S] < T) maxflow += sap(S,INF);
printf("%d\n",maxflow);
for(int i = 0; i <= T; i++) {
h[i] = gap[i]=0;
head[i] = -1;
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: