Considering the contribution of each edge to different coloring schemes, DP is used in a tree-packed manner.
Determine the root and find the size of each node subtree in advance. For the edge u->v, assume that the subtree with v as the root is dyed with k black dots, and the remaining size[v]-k are white dots , the contribution of this edge is e.val*(Kk)*k+e.val*(size[v]-k)*(NK-(size[v]-k), N is the total number of points, K is The total number of points to be dyed black.
This will do DP.
Let f[u][j] denote the optimal value of j black points in the subtree rooted at u, and then use a two-dimensional loop to assign the number of black nodes to u and its child nodes like a backpack.
The allocation link on the tree is written in a two-dimensional loop. I was a little confused when I wrote the first tree package. I was even more confused when I wrote this question, but it is quite a routine to read it now.
There is also complexity, because the total time complexity is O (n 2 ) because of enumerating point pairs, I will not count it.
Twenty days ago, I handed in the program T with three points, and I couldn't survive it. I said that the tree package was very difficult to write, and it was written as O ( n 3 ) at once. I wrote it again today, but the A was lost, so I re-evaluate After a bit of the previous code,,,,, it has passed, and it runs faster than today. Therefore, it is said that Mr. Ji is in a good mood recently.
// qc #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long LL; const int M=2000+10; struct Edge { int u,v,nex,val; Edge() {} Edge(int a,int b,int c,int d):u(a),v(b),nex(c),val(d) {} }ed[M<<1]; int cnt,head[M]; void add_edge(int a,int b,int c) { ed[cnt]=Edge(a,b,head[a],c); head[a]=cnt++; ed[cnt]=Edge(b,a,head[b],c); head[b]=cnt++; } int N,K,size[M]; LL f[M][M]; void dfs1(int u) { size[u]=1; int i; Edge e; for(i=head[u];i!=-1;i=ed[i].nex) { e=ed[i]; if(!size[e.v]) { dfs1 (ev); size[u]+=size[e.v]; } } } void dfs(int u,int fa) { int i,j,k; LL tmp; Edge e; f[u][0]=f[u][1]=0; for(i=head[u];i!=-1;i=ed[i].nex) { e=ed[i]; if (ev! = fa) { dfs (ev, u); for(j=size[u];j>=0;j--) { for(k=0;k<=j&&k<=size[e.v];k++) { tmp=(LL)(K-k)*k*e.val; tmp+=(LL)(size[e.v]-k)*(N-K-(size[e.v]-k))*e.val; tmp+=f[ev][k]; f[u][j]=max(f[u][j],f[u][j-k]+tmp); } } } } } int main() { freopen("haoi2015_t1.in","r",stdin); freopen("haoi2015_t1.out","w",stdout); memset(head,-1,sizeof(head)); scanf("%d%d",&N,&K); int a,b,c; for(int i=1;i<N;i++) { scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); } for(int i=1;i<=N;i++) for(int j=0;j<=K;j++) f[i][j]=-(int)1e9; dfs1 (1); dfs(1,0); printf("%lld\n",f[1][K]); return 0; }