Question: n soldiers are given, of which 1 is the Commander. The relationship is tree structure, and the leaves are pioneers. Now we need to cut off all the pioneers and commanders when the total cost is less than m, what is the maximum limit?
Http://acm.hdu.edu.cn/showproblem.php? Pid = 1, 3586
The question is the minimum and maximum limit.
Then, for each value, the tree-like DP determines whether it is feasible
Dp [I] indicates the minimum cost of splitting all the other subtree rooted in I.
The cost of setting the leaf node is infinite.
For a non-leaf node, there are two options to cut off a subtree: Cut off the subtree rooted in the child or cut off the edges between the root and the child.
If the edges between the root and the child are greater than the limit, then the infinity is obtained.
Finally, determine whether the total cost of Node 1 is less than or equal to m.
Note: Do not set the value of infinity to be too large. Otherwise, the number of consecutive additions will overflow.
[Cpp]
# Include <iostream>
# Include <fstream>
# Include <iomanip>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <cstdlib>
# Include <cmath>
# Include <set>
# Include <map>
# Include <queue>
# Include <stack>
# Include <string>
# Include <vector>
# Include <ctime>
# Include <sstream>
# Include <cassert>
# Define LL long
# Define eps 1e-7
# Define zero (a) fabs (a) <eps
# Define inf 1 <20
# Define N 100005
# Define pi acos (-1.0)
# Define pb (a) push_back ()
# Define lson step <1
# Define rson step <1 | 1
Using namespace std;
Struct Node {
Int v, w, next;
} Edge [2, 100005];
Int start [1005], tot;
Int n, m, dp [1005];
Void addedge (int u, int v, int w ){
Edge [tot]. v = v; edge [tot]. w = w;
Edge [tot]. next = start [u];
Start [u] = tot ++;
}
Void _ addedge (int u, int v, int w ){
Addedge (u, v, w );
Addedge (v, u, w );
}
Void dfs (int u, int limit, int pre ){
Bool flag = false;
For (int I = start [u]; I! =-1; I = edge [I]. next ){
Int v = edge [I]. v, w = edge [I]. w;
If (v = pre) continue;
Flag = true;
Dfs (v, limit, u );
Dp [u] + = min (dp [v], w> limit? Inf: w );
}
If (! Flag) dp [u] = inf;
}
Bool check (int limit ){
Memset (dp, 0, sizeof (dp ));
Dfs (1, limit,-1 );
// Cout <limit <"" <dp [1] <"" <dp [2] <"<dp [3] <"" <dp [4] <endl;
If (dp [1]> m) return false;
Return true;
}
Int main (){
While (scanf ("% d", & n, & m )! = EOF & n + m ){
Tot = 0; memset (start,-1, sizeof (start ));
For (int I = 1; I <n; I ++ ){
Int u, v, w;
Scanf ("% d", & u, & v, & w );
_ Addedge (u, v, w );
}
Int low = 0, high = m, mid, OK = 0, ans =-1;
While (low <= high ){
Mid = (low + high)/2;
If (check (mid) {ans = mid; high = mid-1 ;}
Else low = mid + 1;
}
Printf ("% d \ n", ans );
}
Return 0;
}