A tree that allows you to go from node 1 to node n within the specified time T and obtain the most valuable data.
It is easy to think of a tree-like DP. dp [u] [t] indicates the maximum value that can be obtained when the u subtree is at a distance of t Length, then, each point on the 1-n chain is allocated with a backpack with a capacity of T.
It is actually a group backpack. Each point on the chain represents each group, and items in each group are in the obtained status dp [u] [0-> t]. each group must have at least one item.
Another note is that the edge weight may be 0, so pay attention to it in the Process of tree DP transfer.
Use the tmp variable for transfer in the future --
[Cpp]
# Include <cstdio>
# Include <cstring>
# Include <set>
# Include <string>
# Include <iostream>
# Include <cmath>
# Include <vector>
# Include <map>
# Include <stack>
# Include <time. h>
# Include <queue>
# Include <cstdlib>
# Include <algorithm>
Using namespace std;
Const int maxn = 110;
# Define lowbit (x) & (-(x )))
# Define sqr (x) * (x ))
# Define PB push_back
# Define MP make_pair
Typedef unsigned long ULL;
Typedef long LL;
Typedef vector <int> VI;
Typedef vector <string>;
Typedef pair <int, int> PII;
Vector <PII> edge [maxn];
Int n, T;
Int val [maxn];
Int pre [maxn];
Bool flag [maxn];
Void dfs1 (int u, int f)
{
If (u = n)
{
Pre [u] = f;
Return;
}
For (int I = 0; I <edge [u]. size (); I ++)
{
Int v = edge [u] [I]. first;
If (v = f) continue;
Pre [v] = u;
Dfs1 (v, u );
}
}
Int dp [maxn] [510];
Void Max (int & a, int cmp ){
If (cmp> a) a = cmp;
}
Void dfs (int u, int f, int T)
{
Dp [u] [0] = val [u];
For (int I = 0; I <edge [u]. size (); I ++)
{
Int v = edge [u] [I]. first;
If (v = f | flag [v]) continue;
Int w = edge [u] [I]. second;
Dfs (v, u, T-w );
For (int x = T; x> = 0; x --)
{
Int tmp =-1;
For (int I = 0; I <= x; I ++) if (x-i-2 * w> = 0 & dp [v] [x-i-2 * w]! =-1 & dp [u] [I]! =-1)
{
Max (tmp, dp [u] [I] + dp [v] [x-i-2 * w]);
}
Max (dp [u] [x], tmp );
}
}
}
Int ans [510];
Int mm [maxn] [maxn];
Int main ()
{
Int a, B, c;
While (scanf ("% d", & n, & T )! = EOF)
{
For (int I = 1; I <= n; I ++) edge [I]. clear ();
For (int I = 1; I <n; I ++)
{
Scanf ("% d", & a, & B, & c );
Edge [a]. PB (MP (B, c ));
Edge [B]. PB (MP (a, c ));
Mm [a] [B] = mm [B] [a] = c;
}
For (int I = 1; I <= n; I ++) scanf ("% d", & val [I]);
Memset (pre,-1, sizeof (pre ));
Memset (flag, false, sizeof (flag ));
Dfs1 (1, 0 );
Flag [1] = true;
Int test = 0;
For (int I = n; I! = 1; I = pre [I])
{
Test + = mm [I] [pre [I];
Flag [I] = true;
}
If (test> T)
{
Printf ("Human beings die in pursuit of wealth, and birds die in pursuit of food! \ N ");
Continue;
}
T-= test;
Memset (dp,-1, sizeof (dp ));
For (int I = 1; I <= n; I ++) if (flag [I]) dfs (I, 0, T );
Memset (ans,-1, sizeof (ans ));
Ans [0] = 0;
For (int I = n; I! =-1; I = pre [I])
{
For (int m = T; m> = 0; m --)
{
For (int j = 0; j <= m; j ++) if (ans [m-j]! =-1 & dp [I] [j]! =-1)
{
Max (ans [m], ans [m-j] + dp [I] [j]);
}
}
}
Int ret = 0;
For (int I = 0; I <= T; I ++) Max (ret, ans [I]);
Printf ("% d \ n", ret );
}
Return 0;
}
/*
4 3
1 4 1
4 2 0
2 3 1
10 10 10 10
5 3
1 5 1
5 2 0
2 3 0
3 4 1
10 10 10 10 10 10
*/