# (Tree moving Regulation) Luo Gu P3177 [HAOI2015] tree staining (provincial election / NOI-)

Title Description

There are a number of points N of the tree, the tree has a side edge weights. To give you a positive integer from 0 to K of the N, you have to choose K points in the tree, which was dyed black, and other NK colored white spots. After all points staining, you will get the distance between every two black dots together and the distance between the white point twenty-two benefit. Q. What is the maximum benefit.

Input Format

The first line contains two integers N, K. Then N-1 three lines each positive integers fr, to, dis, in the tree indicates the presence of an edge length of the dis (fr, to). Input to ensure all points are between Unicom.

Output Format

Output a positive integer representing the maximum benefits.

Sample input and output

Input # 1
3 1
1 2 1
1 3 2
Output # 1
3

Description / Tips

To 100% of the data, 0 <= K <= N <= 2000

Author:  __stdcall  Updated: 2016-12-02 16:39   view Ta's blog  61 


HAOI the title, write the person is less, but it sounds like a good title track to the top out of

It should be very easy to think, dp can do is

State is very easy to think, DP [u] [i] u is expressed with the sub-tree, select i black nodes, the maximum

Then I would not do it, go online to read the explanations wmdcstdio God Ben

I find this state definition is wrong, the correct status should be, dp [u] [i] u is represented with sub-tree, select i black nodes, how many answers contribution

Why say "how many contributions to answer it"?

The main thing is to think that each side separately consider the contribution of the answer

That is, the black side of the edge nodes black * * number of nodes on the other side of the right edge side nodes + white white * * number of nodes on the other side of the right side

This is easy to prove, but not easy to think (because I was too weak)

Then the situation is clear, the whole issue has become a tree backpack, consider each child node number of black nodes (volume) distribution, and then calculate the contribution of this edge of the answers (value)

Here again "contribution", because of this contribution not only in the current sub-tree, but it's for the whole tree

Transfer equation dp [u] [i] = max (dp [u] [i], dp [u] [ij] + dp [v] [j] + val)

Wherein v is the child node u, j is the number of the selected child node in the black dots, val contribution of this edge

val = j * (kj) * w + (Sz [v] -j) * (n-k + j-Sz [v]) * w

Where w is the right side of this edge, n is the total number of nodes, k is the total number of nodes need to select black, sz [v] is the number of nodes in the subtree rooted at v is the

//

Solution to a problem of solving the problem has been quite a lot, but I think not enough to make a clear analysis of the questions, especially for the part of DP. So I hope that my solution of this problem can build on the solution to a problem before you on, so that we have a clearer understanding.

To emphasize the details of this question is very important, we must pay attention!


The subject of the request k dyed black dots, black dots twenty-two seek distance and white point twenty-two distance, making them the largest sum.

We can be converted to the path distance, and then split into the route path side, it may be recorded many times each edge is passed, can be calculated directly.

Very simple, right? So the question is, from a good understanding into the path, the path is split edge Hao said, but the number of times each edge is through the how to calculate it?

We may think we take any two points of the same color, for each edge, if not in the path of these two points, we naturally do not consider, if two points on the path, then count this edge plus One. We can convert it, if two points on the side edge, not counting the influence, if the side edges, the edge count by one. So what we promote, we can draw on both sides of one side of each of a pair of the same color point, this edge would be through once. That is, the number of times an edge is equal to the product after the same number of sides of the color point of the edge. Then we can find the number of times each edge is passed

tot = k * (mk) + (c [v] k) * (nm No [v] + k) t p t = k * ( mk ) + ( s z [ v ] - k ) * ( n - m - s z [ v ] + k )

m m represents the number of black dots is selected from questions asked, SZ [V] S Z [ V ] denotes the size of the current sub-sub-tree nodes, K K represents the current sub-tree, child nodes selected number of black dots

With this conclusion, we can easily draw the DP equation.

f [u] [j] = max (f [u] [j], f [u] [jk] + f [v] [k] + to * e [i] .w) f [ can ] [ j ] = m a x ( f [ can ] [ j ] , f [ can ] [ j - k ] + f [ v ] [ k ] + t o t * e [ i ] . w )

This equation is about let me do question when tangled for a long time, why k k positive sequence arrangement is right, the reverse order is wrong? Existing explanations did not make a good explanation, I did not continue to study after the A. Thanks to help students find when a tree DP re-entry problem I noticed this question, so I had doubts about this strange phenomenon. After obtaining help DDOSvoid chiefs and conducted several tests, I finally understand the reasons, but also to deepen my understanding of this question of several layers.

This question k reasons before several explanations k must be positive sequence enumeration is not a use JK JK update the answer, but because of the positive sequence enumeration k k is from 0 zero, and solving the problem state transfer must first be k = 0 k = 0 transferred from the state can be established. In other words, this is just a coincidence, J J enumeration to reverse is true, but k k enumeration must be positive sequence is simply nonsense. To avoid this situation, just ahead of a diversion of k = 0 k = 0 can be.

Put the following code (there are notes)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc getchar
#define maxn 2005
using namespace std;

inline ll read(){//KD
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}

struct ahaha {// definition of adjacency list
int W, to, Next;
} E [MAXN <<. 1]; int TOT, head [MAXN];
inline void the Add (int U, V int, int W) {
E [TOT] = W .W, E [TOT] .to = V, E [TOT] head .next = [U]; head [U] = TOT ++;
} // bordered operation

n-int, m, SZ [MAXN];
LL F [MAXN] [MAXN]; // F [i] [j] denotes the subtree rooted at i, j smear black dots contribution
void dfs (int u , int fa) {// u its father node
sz [u] = 1; f [u] [0] = f [u] [1] = 0; // initialize point nodes u 1 to u node is the root, or u 0 applicator
applicator black // node, u -> v must not contribute to this edge!
for (int i = head [u ]; ~ i; i = e [i] .next) {// for all edges connected son u
int v = e [i] .to ; if (v == fa) continue ; //
DFS (V, U); SZ [U] = SZ + [V]; // child node number calculated
for (int j = min (m , sz [u]); j> = 0; - j) {// is equivalent to the number of the white point up to the applicator /
// white dots applied to the maximum extent permitted subtree
if (f [u] [j ] = -! 1) // If u, j has been defined the
F [U] [J] = F + [V] [0] + (LL) SZ [V] * (nm-SZ [V]) * E [I] .W; //
// consider the whole subtree white case
for (int k = min (j , sz [v]); k; - k) {// iterate through all the white points may
if (f [u] [jk ] == - 1) continue; / / u root, jk is not of a black
// i.e. no way transferred from the front over
ll val = (ll) (k * (mk) + (sz [v] -k) * (nm-sz [v ] + k)) * e [ i] .w; //
// calculate the total contribution
f [u] [j] = max (f [u] [j], f [u] [jk] + f [v] [k] + val); // update
// U apply node j black dots edge contribution to the total value
} //
} //
}
}

int main(){memset(head,-1,sizeof head);//初始化
n=read();m=read();//
if(n-m<m)m=n-m;//转化为白点
for(int i=1;i<n;++i){//
int u=read(),v=read(),w=read();//
add(u,v,w);add(v,u,w);//
}memset(f,-1,sizeof f);//
dfs(1,-1);//
printf("%lld",f[1][m]);//
return 0;
}

Guess you like

Origin www.cnblogs.com/little-cute-hjr/p/11441572.html