1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<climits> #include<vector> #include<cstdio> #include<cmath> #include<queue>
using namespace std;
inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(!isdigit(x)) { if(x=='-')bj=-1; x=getchar(); } while(isdigit(x)) { num=num*10+x-'0'; x=getchar(); } return num*bj; }
const int maxn=20005,maxnm=26000005;
int n,m,Wid,Len,f[maxnm],g[maxnm],fa[maxn],ans=0; vector<int> edges[maxn];
void AddEdge(int x,int y) { edges[x].push_back(y); }
struct Thing { int num,value; } a[maxn];
#define pii pair<int,int> #define mp make_pair
void trans(int *f,const Thing& a) { deque<pii>Q; for(int i=0; i<=m; i++) { while(!Q.empty()&&Q.front().first<i-a.num)Q.pop_front(); while(!Q.empty()&&Q.back().second<=f[i]-i*a.value)Q.pop_back(); Q.push_back(mp(i,f[i]-i*a.value)); f[i]=Q.front().second+i*a.value; } }
void Dfs1(int Now) { if(a[Now].num)trans(f+Now*Wid,a[Now]); for(int Next:edges[Now]) { memcpy(f+Next*Wid,f+Now*Wid,Len); Dfs1(Next); for(int j=1,*p=f+Now*Wid+1,*q=f+Next*Wid; j<=m; j++,p++,q++)*p=max(*p,*q+a[Next].value); } }
void Dfs2(int Now,int sum) { sum+=a[Now].value; for(int Next:edges[Now]) { memcpy(g+Next*Wid,g+Now*Wid,Len); Dfs2(Next,sum); for(int j=1,*p=g+Now*Wid+1,*q=g+Next*Wid; j<=m; j++,p++,q++)*p=max(*p,*q+a[Next].value); } if(!edges[Now].size())for(int j=0,*p=f+Now*Wid+m,*q=g+Now*Wid; j<=m; j++,p--,q++)ans=max(ans,*p+*q+sum); if(a[Now].num)trans(g+Now*Wid,a[Now]); }
void Clear() { for(int i=1; i<=n; i++)edges[i].clear(); memset(f+Wid,0,Len); memset(g+Wid,0,Len); ans=0; }
int main() { int t=Get_Int(); while(t--) { Clear(); n=Get_Int(); m=Get_Int(); Wid=m+1;Len=Wid*sizeof(int); for(int i=1; i<=n; i++) { fa[i]=Get_Int(); if(fa[i])AddEdge(fa[i],i); a[i].num=Get_Int()-1; a[i].value=Get_Int(); } Dfs1(1); for(int i=1; i<=n; i++)edges[i].clear(); for(int i=n; i>=1; i--)if(fa[i])AddEdge(fa[i],i); Dfs2(1,0); printf("%d\n",ans); } return 0; }
|