The main idea: a tree with n nodes has a root tree, 1 is the root node, edge with right, indicating the cost of deleting this edge. Now remove some edges so that the leaf node cannot reach the root node. However, the cost of each deleted edge cannot exceed limit, and the total cost of the deleted edge cannot exceed M, which is the possible value of the minimum limit.
Topic Analysis: Two-point enumeration of limit, defined state DP (U) represents the total cost of losing contact with the leaf node to which it is governed:
DP (U) +=min (DP (son), E[I].W),e[i].w<=limit;
DP (U) +=DP (son) e[i].w>limit;
The code is as follows:
# include<iostream># include<cstdio># include<cstring># include<vector># include<queue ># include<list># include<set># include<map># include<string># include<cmath># include<cstdlib># include<algorithm>using namespace std;# define LL long longconst int n=1005;const int INF=1 000001;struct edge{int w,to,nxt;}; Edge e[n];int n,m;int du[n];int maxn,cnt;int dp[n];int head[n];void Add (int u,int v,int W) {e[cnt].to=v;e[cnt].w=w;e[cnt] . nxt=head[u];head[u]=cnt++;} void init () {int A,b,c;cnt=maxn=0;memset (du,0,sizeof (du)); Memset (Head,-1,sizeof (head)); for (int i=1;i<n;++i) { scanf ("%d%d%d", &a,&b,&c); ++du[a];++du[b];maxn=max (maxn,c); add (a,b,c); add (b,a,c);}} void Dfs (int u,int fa,int limit) {//cout<<u<<endl;if (du[u]==1&&u!=1) {Dp[u]=inf;return;} dp[u]=0;for (int i=head[u];i!=-1;i=e[i].nxt) {int v=e[i].to;if (V==FA) Continue;dfs (V,u,limit), if (E[i].w>limit) DP [U]+=dp[v];elsedp[u]+=min (DP[V],E[I].W);}} int soLve () {if (n==1) return 0;int l=1,r=maxn+1;while (l<r) {int mid=l+ (r-l)/2;dfs (1,-1,mid); if (dp[1]>m) l=mid+1;elser =mid;} DFS (1,-1,R); if (dp[1]>m) Return-1;return R;} int main () {//new theme while (~SCANF ("%d%d", &n,&m) && (n+m)) {init ();p rintf ("%d\n", Solve ());} return 0;}
HDU-3586 Information disturbing (tree-shaped dp+ Delete)