For a given tree, each node has a weight value. You must select the K points with the highest total weight. At the same time, any of the K points cannot be the ancestor of other nodes ..
Analysis: Ha, I feel like a tree-shaped backpack as soon as I see the question, but there are too many nodes and 150000 nodes. If I save it with a two-dimensional array, it's easy to write, however, the memory is definitely exploding, so a temporary array is enabled to save
The model is very similar to the general tree-like backpack.
View code
# Include <algorithm>
# Include <vector>
# Include <iostream>
Using Namespace STD;
Const Int N = 150010 ;
Vector < Int > G [N];
Int N, DP [ 310 ], K, W [N];
Void Init ()
{
For ( Int I = 0 ; I <= N; I ++)
G [I]. Clear ();
}
Int DFS ( Int U)
{
Int Size = G [u]. Size ();
Int T = 0 ; // Number of statuses generated for saving the current subtree
Int Cur [ 310 ]; // Saves the current subtree's backpack status
For ( Int I = 1 ; I <= K; I ++)
DP [I] = cur [I] =-int_max;
Cur [ 0 ] = DP [0 ] = 0 ;
For ( Int I = 0 ; I <size; I ++)
{
Int V = G [u] [I];
Int Now = DFS (v ); // Find the number of states of the V branch and save the status of the backpack in the DP array.
For ( Int J = T; j> =0 ; J --) // Number of status generated by the current subtree
{
For ( Int K = 1 ; K <= now; k ++) // Number of statuses generated by the subtree traversed by the V Node
{
If (K + j> K)
Break ;
Cur [K + J] = max (cur [K + J], DP [k] + cur [J]);
}
}
T + = now; // After the combination of the two parts, add the number of states of the V branch to the current subtree.
}
If (Size = 0 ) // Because this step is missing, WA spent one night ...... Because the parent node is compared with cur [1] After the son's status number combination, no status number is generated. T must be accumulated only when the current node is a leaf node
T ++;
Cur [ 1 ] = Max (cur [ 1 ], W [u]); // Note: The root node must be added after the entire subtree is finished with the backpack, because the parent node cannot be added to the child node and cannot be added to the backpack at the same time.
For ( Int I = 0 ; I <= K; I ++) // Save the status of the current subtree to the DP array.
DP [I] = cur [I];
Return T; // Returns the total number of statuses generated by the current subtree.
}
Int Main ()
{
Int X, root;
While (Scanf ( " % D " , & N, & K) = 2 )
{
Init ();
For ( Int I = 1 ; I <= N; I ++)
{
Scanf ( " % D " , & X, & W [I]);
If (X = 0 )
Root = I; // Find the root node
Else
G [X]. push_back (I );
}
DFS (Root );
If (DP [k] =-int_max)
Printf ( " Impossible \ n " );
Else Printf ( " % D \ n " , DP [k]);
}
Return 0 ;
}