subject Given n n n enemy strongholds, 1 is the headquarters, and the other points are connected by one side to form a tree. Each side has a weight cost to represent the cost of destroying this side, and the leaf node is the front line. To cut off the contact between the front line and the headquarters, the cost of each cut-off should not exceed the upper limit. The total cost of cutting off all the front lines with the headquarters is less than the minimum limit when the total cost is less than m. (1<=n<=1000,1<=m<=1e6)
Divided limit, dp[u] denotes the minimum cost of all leaf nodes removing the subtree u, dp[u]=min(w[u], Sigma (dp[v]); w [u] denotes cutting off the edge weight between u and its parent node, and dp[v] is the optimal value of the child node.
#include <bits/stdc++.h> using namespace std; const int maxn=1010; #Definition inf 1000001/// Dead people int n,m; struct node{ int x,w; node(int _x,int _w) { x=_x; w=_w; } }; vector<node>a[maxn]; int limit,dp[maxn]; void dfs(int u,int fa) { int flag=0,tmp=0; for(int i=0;i<a[u].size();i++) { int v=a[u][i].x,w=a[u][i].w; if(v==fa) continue; flag=1; if(w<=limit) dp[v]=w;//Direct shearing dfs(v,u); tmp+=dp[v];//Calculate sigma (dp[v]) } if(flag==1)//Transfer occurs when u is not a leaf node dp[u]=min(dp[u],tmp);//dp[u] in min function is the cost of direct clipping temporarily stored } bool check(int fuck) { limit=fuck; for(int i=1;i<=n;i++) dp[i]=inf;//// Don't take too much inf, otherwise the sum explosion int used later, 1e6+1 is just right. dfs(1,-1); return dp[1]<=m;/// } int main() { //cout << "Hello world!" << endl; //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m),n+m) { for(int i=1;i<=n;i++) a[i].clear(); for(int i=1;i<n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); a[x].push_back(node(y,z)); a[y].push_back(node(x,z)); } int l=0,r=m,ans=-1; while(l<r-1) { int mid=(l+r)/2; if(check(mid)) r=mid; else l=mid; } if(check(r)) ans=r; if(check(l)) ans=l; printf("%d\n",ans); } return 0; }