Title [brush] [dp] tree

1> tree coloring

(Explanations copied from luogu)

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.

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cstring>
#define ll long long
using namespace std;
ll n,k;
const int N=2003;
struct node
{
    int v,w;
    node(int vv,ll ww)
    { v=vv,w=ww; }
    node(){}
};
vector <node> g[N];

ll sz[N];
ll f[N][N];
void dfs(int rt,intFA) 
{ 
    SZ [RT] = . 1 , F [RT] [ 0 ] = F [RT] [ . 1 ] = 0 ;
     // value of the illegal state can be large, so it is still Memset 
     int S = G [RT] .size ();
     for ( int I = 0 ; I <S; I ++ )
         IF (! G [RT] [I] .v = FA) 
            DFS (G [RT] [I] .v, RT), SZ [ RT] + = SZ [G [RT] [I] .v]; 
    
    for (LL I = 0 ; I <S; I ++ ) 
    { 
        Node NX = G [RT] [I];
         IF (FA == nx.v ) the Continue ;
        
    for (LL J = min (SZ [RT], K); J> = 0 ; J,) // The following are just as well not write // reverse only, did not write, the state will be repeated calculation 
            for (LL L = 0 ; L <= SZ [nx.v] && L <= J; L ++ ) 
            { 
                IF (F [RT] [JL] == - . 1 ) Continue ; 
                
                LL Val = nx.w * L * (kl to) + * nx.w (SZ [nx.v] -l) * (NK-SZ [nx.v] + L); 
                F [RT] [J] = max (F [RT] [J], F [RT] [JL] + F [nx.v] [L] + Val); 
            } 
    } 
} 

int main () 
{ 
    Scanf ( " % D% D " , & n-, & K); 
    K = min (K, N-k);
    int u,v;ll w;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%lld",&u,&v,&w);
        g[u].push_back(node(v,w)) ;
        g[v].push_back(node(u,w));
    }
    
    memset(f,-1,sizeof(f));
    dfs(1,-1);
    printf("%lld\n",f[1][k]);
    
    return 0; 
}

2> digital conversion

 

 

Guess you like

Origin www.cnblogs.com/xwww666666/p/11647104.html