[HAOI2015] Dyeing on the tree

  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;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324460272&siteId=291194637