★★☆ input file: haoi2015_t1.in
output file: haoi2015_t1.out
Simple comparison
Time limit: 1 s memory limit:
"Title description"
There is a tree with a number of N, and the edge of the tree is right. Give you a positive integer in 0~n K, you want to select the K point in this tree, dye it black, and turn the other n-k Dianran into white. After all points are dyed, you will get the distance between the black Point 22 plus the white dot 22 distance between the and the proceeds. Ask what is the maximum value of the revenue.
"input Format"
The first row of two integers n,k.
The next N-1 line has three positive integer fr,to,dis per line, indicating that there is an edge (fr,to) of dis in the tree. Enter to ensure that all points are connected to each other.
"Output format"
Outputs a positive integer that represents the maximum value of the benefit.
"Input Sample 1"
3 1
1 2 1
1 3 2
"output Example 1"
3
"Input Sample 2"
5 2
1 2 3
1 5 1
2 3 1
2 4 2
"Output Example 2"
17
"Sample Interpretation"
In the second example, the dots are dyed black to get the most benefit.
"Data range"
For 30% of data, n<=20
For 50% of data, n<=100
For 100% of data, n<=2000,0<=k<=n
Exercises
This is a tree-shaped DP, considering for each edge, its contribution to the answer = the number of black dots at both ends of the product * edge weight + Both ends of the white point number product * edge right.
F[I][J] represents the maximum benefit of J black dots in a subtree that is rooted in I. For a node x and one of its sons Y, considering the contribution of X and Y to the answer, we can first enumerate the number of black dots in X, then enumerate the number of black dots in Y, and use a similar 01 backpack to transfer.
1 /**************************************************************2 problem:40333 User: __abcdef__4 language:c++5 result:accepted6 time:6824 Ms7 memory:32932 KB8 ****************************************************************/9 Ten#include <iostream> One#include <cstdio> A#include <cstdlib> -#include <cstring> -#include <cmath> the#include <algorithm> -#include <queue> -#include <vector> - using namespacestd; +typedefLong LongLL; - ConstLL inf=1e15,maxn= .; + LL n,k; AVector<ll>TO[MAXN],COST[MAXN]; at LL FA[MAXN],F[MAXN][MAXN],SIZ[MAXN]; -Inlinevoiddfs (LL x,ll fath) { -Fa[x]=fath; siz[x]=1; - for(intI=0; I<to[x].size (); i++){ -LL y=To[x][i]; - if(y!=Fath) { in DFS (y,x); -siz[x]+=Siz[y]; to } + } - } the *InlinevoidCalc (LL x) {//calculate the case with X as the root $f[x][0]=0; f[x][1]=0;Panax Notoginseng if(siz[x]==1)return;//leaf node - for(intI=0; I<to[x].size (); i++) {//Enumerating subtrees theLL y=to[x][i],val=Cost[x][i]; + if(y!=Fa[x]) { A Calc (y); the for(intTot=min (K,siz[x]); tot>=0; tot--) {//enumerates a few black dots in a subtree with x as its root + for(intj=0; J<=min (siz[y],k) &&j<=tot;j++) {//How many black dots are in this subtree? -ll ans1= (LL) j* (K (LL) j) *Val; $ll ans2= (siz[y]-(LL) j) * (n-k-(siz[y]-(LL) j)) *Val; $LL tmp=f[y][j]+ans1+Ans2; -F[x][tot]=max (f[x][tot],f[x][tot-j]+tmp); - } the } - }Wuyi } the } - Wu intMain () { -scanf"%lld%lld",&n,&K); About for(intI=1; i<=n-1; i++){ $ LL u,v,c; -scanf"%lld%lld%lld",&u,&v,&c); - To[u].push_back (v); Cost[u].push_back (c); - to[v].push_back (U); Cost[v].push_back (c); A } + for(intI=1; i<=n;i++){ the for(intj=1; j<=n;j++){ -f[i][j]=-inf; $ } the } theDfs1,-1); theCalc1); theprintf"%lld\n", f[1][k]); - return 0; in}
Cogs 1962. [HAOI2015] staining on trees