【HAOI2015】【树形dp】树上染色

【题目描述】

有一棵点数为N的树,树边有边权。给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色。将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益。问收益最大值是多少。

【输入格式】

第一行两个整数N,K。

接下来N-1行每行三个正整数fr,to,dis,表示该树中存在一条长度为dis的边(fr,to)。输入保证所有点之间是联通的。

【输出格式】

输出一个正整数,表示收益的最大值。

【输入样例1】

3 1

1 2 1

1 3 2

【输出样例1】

3

【输入样例2】

5 2

1 2 3

1 5 1

2 3 1

2 4 2

【输出样例2】

17

【样例解释】

在第二个样例中,将点1,2染黑就能获得最大收益。

【数据范围】

对于30%的数据,N<=20

对于50%的数据,N<=100

对于100%的数据,N<=2000,0<=K<=N。

题解:

其实这个题只需要考虑每个子树和他父亲的那条边对答案做了多少贡献即可(也就是子树内的白点数乘上子树外的白点数再加上子树内的黑点数乘上子树外的黑点数,最后再乘上边权),这个问题是可以分割成子问题的,对于每个子问题我们就可以枚举父节点给他的每个儿子分多少个黑点,然后就成了树形背包了。

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int n,kk,y,z,x;;
long long f[2010][2010],sz[2010];
vector<pair<int,int> > a[2010];
void dfs(int x,int fa)
{
    f[x][0]=f[x][1]=0;
    int u;
    long long ans;
    sz[x]=1;
    for (int i=0;i<a[x].size();i++)
      {
          u=a[x][i].first;
         if (u==fa) continue;
         dfs(u,x);
         sz[x]+=sz[u];
       for(int j=sz[x];j>=0;j--)
        {
          for(int k=0;k<=sz[u]&&k<=j;k++)
          {
            ans=(long long)(k*(kk-k))+(long long)((sz[u]-k)*(n-kk-(sz[u]-k)));
            ans*=a[x][i].second;
            ans+=f[u][k];
            f[x][j]=max(f[x][j],f[x][j-k]+ans);
          }
        }

      }
}
int main()
{
    freopen("haoi2015_t1.in","r",stdin);
    freopen("haoi2015_t1.out","w",stdout);
    scanf("%d%d",&n,&kk);
    for (int i=1;i<=n-1;i++)
      {
         scanf("%d%d%d",&x,&y,&z);
         a[x].push_back(make_pair(y,z));
         a[y].push_back(make_pair(x,z));
      }
    for (int i=1;i<=n;i++)
      for (int j=1;j<=n;j++)
         f[i][j]=-999999999999;
    dfs(1,0);
    printf("%lld",f[1][kk]);
}
时间: 2024-10-11 11:17:36

【HAOI2015】【树形dp】树上染色的相关文章

HDU 3899 树形DP||树上递推

JLUCPC 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3899 Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1375    Accepted Submission(s): 413 Problem Description Dr. Skywind and Dr. Walkonclo

HDU2376Average distance(树形dp|树上任意两点距离和的平均值)

思路: 引:如果暴力枚举两点再求距离是显然会超时的.转换一下思路,我们可以对每条边,求所有可能的路径经过此边的次数:设这条边两端的点数分别为A和B,那 么这条边被经过的次数就是A*B,它对总的距离和的贡献就是(A*B*此边长度).我们把所有边的贡献求总和,再除以总路径数N*(N-1)/2,即为最 后所求. 每条边两端的点数的计算,实际上是可以用一次dfs解决的.任取一点为根,在dfs的过程中,对每个点k记录其子树包含的点数(包括其自身),设点数为a[k],则k的父亲一侧的点数即为N-a[k].这

【BZOJ4033】[HAOI2015]树上染色 树形DP

[BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益.问收益最大值是多少. Input 第一行两个整数N,K. 接下来N-1行每行三个正整数fr,to,dis,表示该树中存在一条长度为dis的边(fr,to). 输入保证所有点之间是联通的. N<=2000,0<=K&l

[HAOI2015]树上染色(树形dp)

[HAOI2015]树上染色 题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益.问受益最大值是多少. 输入输出格式 输入格式: 第一行包含两个整数 N, K .接下来 N-1 行每行三个正整数 fr, to, dis , 表示该树中存在一条长度为 dis 的边 (fr, to) .输入保证所有点之间是联通的

bzoj4033: [HAOI2015]树上染色(树形dp)

4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3269  Solved: 1413[Submit][Status][Discuss] Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益. 问收益最大值是多少. Input 第一

bzoj 4033: [HAOI2015]树上染色

4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1886  Solved: 805 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益. 问收益最大值是多少. Input 第一行两个整数N,K. 接下来N-1行每行三个正整数fr

[BZOJ4033][HAOI2015]树上染色

试题描述 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益. 问收益最大值是多少. 输入 第一行两个整数N,K. 接下来N-1行每行三个正整数fr,to,dis,表示该树中存在一条长度为dis的边(fr,to). 输入保证所有点之间是联通的. N<=2000,0<=K<=N 输出 输出一个正整数,表示收益的最大值. 输入示例 5

bzoj 4033: [HAOI2015]T1(树形DP)

4033: [HAOI2015]T1 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 819  Solved: 375 [Submit][Status][Discuss] Description 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整 数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的 N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之间的距 离加上白点两两之间的距离的和的受益.问受益最大值是多

cogs 1962. [HAOI2015]树上染色

★★☆   输入文件:haoi2015_t1.in   输出文件:haoi2015_t1.out   简单对比 时间限制:1 s   内存限制:256 MB [题目描述] 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益.问收益最大值是多少. [输入格式] 第一行两个整数N,K. 接下来N-1行每行三个正整数fr,to,dis,表示该树中存

【bzoj3362/3363/3364/3365】[Usaco2004 Feb]树上问题杂烩 并查集/树形dp/LCA/树的点分治

题目描述 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样, 图中农场用F1..F7表示, 每个农场最多能在东西南北四个方向连结4个不同的农场.此外,农场只处在道路的两端.道路不会交叉且每对农场间有且仅有一条路径.邻居鲍伯要约翰来导航,但约翰丢了农场的地图,他只得从电脑的备份中修复了.每一条道路的信息如下: 从农场23往南经距离10到达农场17 从农场1往东经距离7到达农