洛谷P3177

bzoj4033

根本不会做。。。

上网查了题解,发现只要在状态定义的时候就考虑每一条边全局的贡献就好了?

考虑边的贡献和修改状态定义我都想到了,然而并不能想到要结合起来

ans[i][j]表示i子树中选j个黑色节点,最大的贡献和

容易知道:每一条边的贡献为 长度*(边一侧的白点数*边另一侧的白点数+边一侧的黑点数*边另一侧的黑点数)

可以发现,如果已经确定一棵子树中选多少个黑点,那么这棵子树的根到其父亲的连边的贡献可以直接确定

考虑向一棵树的根节点(u)下再加入一棵子树(v)时的转移:sz[u]表示u子树的节点个数

$ans[u][k]=max\{ans[u][i]+ans[v][j]+dis(u,v)*(j*(K-j)+(sz[v]-j)*(n-sz[v]-K+j))\}(k=i+j)$

要构建一棵树,可以先构建完所有以根节点的某个子节点为根的子树,然后再依次将子树与根节点连上边。

复杂度好像是n^3的?事实上只要改一下循环的上界就n^2了。转移某个子树时,i上界为之前已经转移过的子树size和 + 1(根节点自身),j上界为目标子树size

可以发现,树上每一对点对刚好产生1次转移(在lca处产生),因此总复杂度等于总点对数是n^2的

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
struct E
{
ll to,nxt,d;
}e[];
ll f1[],ne;
ll ans[][];
ll sz[];
ll tmp[];
ll n,K;
void dfs(ll u,ll fa)
{
ans[u][]=ans[u][]=;sz[u]=;
ll i,j;
for(ll v,k=f1[u];k;k=e[k].nxt)
if(e[k].to!=fa)
{
v=e[k].to;
dfs(v,u);
memset(tmp,,sizeof(ll)*(sz[u]+sz[v]+));
for(i=sz[u];i>=;--i)
{
for(j=sz[v];j>=;--j)
{
if(K>=j&&n-sz[v]-K+j>=)
{
tmp[i+j]=max(tmp[i+j],ans[u][i]+ans[v][j]
+e[k].d*(j*(K-j)+(sz[v]-j)*(n-sz[v]-K+j)));
}
}
}
for(i=;i<=sz[u]+sz[v];++i)
ans[u][i]=tmp[i];
sz[u]+=sz[v];
}
//printf("1t%lld\n",u);
//for(i=0;i<=sz[u];i++)
// printf("%lld %lld\n",i,ans[u][i]);
}
int main()
{
ll i,x,y,z;
memset(ans,,sizeof(ans));
scanf("%lld%lld",&n,&K);
for(i=;i<n;++i)
{
scanf("%lld%lld%lld",&x,&y,&z);
e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;e[ne].d=z;
e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;e[ne].d=z;
}
dfs(,);
printf("%lld",ans[][K]);
return ;
}

洛谷P3177||bzoj4033 [HAOI2015]树上染色的更多相关文章

  1. BZOJ4033 HAOI2015 树上染色 【树上背包】

    BZOJ4033 HAOI2015 树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白 ...

  2. [BZOJ4033][HAOI2015]树上染色(树形DP)

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2437  Solved: 1034[Submit][Stat ...

  3. BZOJ4033: [HAOI2015]树上染色(树形DP)

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3461  Solved: 1473[Submit][Stat ...

  4. [bzoj4033][HAOI2015]树上染色_树形dp

    树上染色 bzoj-4033 HAOI-2015 题目大意:给定一棵n个点的树,让你在其中选出k个作为黑点,其余的是白点,收益为任意两个同色点之间距离的和.求最大收益. 注释:$1\le n\le 2 ...

  5. 【题解】 bzoj4033: [HAOI2015]树上染色* (动态规划)

    bzoj4033,懒得复制,戳我戳我 Solution: 定义状态\(dp[i][j]\)表示\(i\)号节点为根节点的子树里面有\(j\)个黑色节点时最大的贡献值 然后我们要知道的就是子节点到根节点 ...

  6. 【树形背包】bzoj4033: [HAOI2015]树上染色

    仔细思考后会发现和51nod1677 treecnt有异曲同工之妙 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 ...

  7. [BZOJ4033]:[HAOI2015]树上染色(树上DP)

    题目传送门 题目描述 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加 ...

  8. BZOJ4033 [HAOI2015]树上染色 【树形dp】

    题目 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间 ...

  9. BZOJ4033 [HAOI2015]树上染色

    本来是考虑, $ f[x][i][0/1] $ 表示 $ x $ 子树中有$i$个黑点,且 $ x $ 是白点/黑点.但是这里的答案是要统计不同的子树的贡献的.所以就gg了. 看了题解. 应该是要设$ ...

随机推荐

  1. POJ 1611 The Suspects (并查集+数组记录子孙个数 )

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 24134   Accepted: 11787 De ...

  2. Codeforces Round #105 (Div. 2) E. Porcelain —— DP(背包问题)

    题目链接:http://codeforces.com/problemset/problem/148/E E. Porcelain time limit per test 1 second memory ...

  3. 如何查看智能手机的IP地址

      1.  外网IP IP地址可简单分为两类.外网IP或称公网IP是用来在Internet上唯一标识你的设备的.如果你通过GPRS或者3G技术接入互联网的话(通过运营商网络),那么你也可以通过下面的方 ...

  4. userData IE

    蛮讨厌IE的,因为他常常需要特别照顾,就像DOM Storage(sessionStorage和localStorage)只能支持IE8+,对于以下的只能使用userData. 原理:通过在docum ...

  5. SPOJ:Red John is Back(DP)

    Red John has committed another murder. But this time, he doesn't leave a red smiley behind. What he ...

  6. java中的异常The given object has a null identifier

    修改页面点击提交时报如下异常: org.hibernate.TransientObjectException: The given object has a null identifier: com. ...

  7. Linux系统启动全过程

    分为两部分,第一部分是硬件本身需要加载的信息,之后才是加载Linux相关信息,因为有装有双系统的机器嘛 1.计算机加电 2.BIOS开始运行,检测硬件:cpu.内存.硬盘等 3.BIOS读取CMOS存 ...

  8. 编写 DockerFile

    编写 DockerFile 本节内容简介 在前面的实验中我们多次用到的 Dockerfile,在本实验里我们将通过完成一个实例来学习Dockerfile的编写. 本节中,我们需要依次完成下面几项任务: ...

  9. 通过上一节部署出来的 Windows instance 有时候会发现操作系统时间总是慢 8 个小时,即使手工调整好时间和时区,下次 instance 重启后又会差 8 个小时

    这是 OpenStack 实施经验分享系列的第 3 篇. 问题描述 通过上一节部署出来的 Windows instance 有时候会发现操作系统时间总是慢 8 个小时,即使手工调整好时间和时区,下次 ...

  10. 使用BFG清除git仓库中的隐私文件或大文件

    使用git时间不长,在调机械臂项目的时候,由于对TwinCAT3和vs的机制不太了解,没有添加很好的忽略文件(.gitignore).造成git仓库包含了很多没有用的文件,例如vs的sdf文件,Twi ...