码迷,mamicode.com
首页 > 其他好文 > 详细

P3177 [HAOI2015]树上染色

时间:2020-11-16 13:35:00      阅读:7      评论:0      收藏:0      [点我收藏+]

标签:space   har   const   dfs   std   表示   fir   黑点   return   

链接

我好菜啊。。。

考虑每条边对答案的贡献为多少。

显然可以定义状态 \(f_{i,j}\) 表示 \(i\) 子树中有 \(j\) 个黑点,子树中每条边对答案贡献之和的最大值。

于是合并就是背包,方程为 \(f_{u,i+j}=f_{u,i}+f_{v,j}+((k-j)*j+((n-k)-(siz_v-j))*(siz_v-j))\)

注意倒序枚举。

#include<bits/stdc++.h>
#define IL inline
#define LL long long
using namespace std;
const int N=2e3+3;
struct hh{
	int to,nxt,w;
	}e[N<<1];
int n,m,num,fir[N],siz[N];
LL f[N][N],g[N];
IL int in(){
	char c;int f=1;
	while((c=getchar())<‘0‘||c>‘9‘)
		if(c==‘-‘) f=-1;
	int x=c-‘0‘;
	while((c=getchar())>=‘0‘&&c<=‘9‘)
		x=x*10+c-‘0‘;
	return x*f;
	}
IL void add(int x,int y,int z){e[++num]=(hh){y,fir[x],z},fir[x]=num;}
void dfs(int u,int fa){
	siz[u]=1;
	for(int i=fir[u],v;v=e[i].to;i=e[i].nxt)
		if(v^fa){
			dfs(v,u);
			for(int j=siz[u];~j;--j)
				for(int k=siz[v];~k;--k) if(j+k<=m)
					f[u][j+k]=max(f[u][j+k],f[u][j]+f[v][k]+1ll*e[i].w*((m-k)*k+(n-m-(siz[v]-k))*(siz[v]-k)));
			siz[u]+=siz[v];
			}
	}
int main()
{
	int x,y,z;
	n=in(),m=in();
	for(int i=1;i<n;++i)
		x=in(),y=in(),z=in(),
		add(x,y,z),add(y,x,z);
	dfs(1,0);
	cout<<f[1][m]<<endl;
	return 0;
	}

P3177 [HAOI2015]树上染色

标签:space   har   const   dfs   std   表示   fir   黑点   return   

原文地址:https://www.cnblogs.com/yiqiAtiya/p/13954351.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!