题目描述

有一棵点数为 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

说明

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


求染色后黑点间距离之和加白点间距离之和之和的最大值,考虑去掉后效性的方法

对于每一棵子树来说,其对于答案的贡献其实只有子树内同色点距离和,和黑点到子树根的距离和\(*\)子树外黑色点的个数+白色点到子树根的距离和\(*\)子树外白色点的个数,就可以转移了,\(f[i][j]\) 表示\(i\)及其子树内染黑\(j\)个点能都得到的最大收益。

由于子树根节点的颜色对于其子树的答案是没有贡献的(...) 所以把根节点染黑的情况就是\(f[i][j]=f[i][j-1]\)(...)

然后直接转移就行了啊

需要注意的是因为一棵子树都是必须要选的,是不能直接不选的,直接更新会对后面的更新在成影响,所以先建一个\(g\)数组在每一次用一棵新子树跟新答案时记录新答案,然后直接用其更新\(f\)数组的值即可


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; long long i,m,n,j,k,ver[10001],head[10001],nex[10001],edge[10001],z,cnt,x,y,f[2001][2001],g[2001],size[10001]; void add(long long x,long long y,long long z)
{
cnt+=1;
ver[cnt]=y;
nex[cnt]=head[x];
head[x]=cnt;
edge[cnt]=z;
} void dfs(long long now,long long fa)
{
f[now][0]=0;
for(int i=head[now];i;i=nex[i])
{
int t=ver[i];
if(t==fa) continue;
dfs(t,now);
memset(g,-0x3f,sizeof(g));
size[now]+=size[t]; for(long long j=min(size[now],m);j>=0;j--)
for(int l=0;l<=min(size[t],j);l++)
g[j]=max(g[j],f[now][j-l]+f[t][l]+edge[i]*l*(m-l)+edge[i]*(size[t]-l)*(n-m-size[t]+l)); for(int j=0;j<=min(size[now],m);j++) f[now][j]=g[j];
}
size[now]+=1;
if(size[now]==1) f[now][1]=0;
f[now][size[now]]=f[now][size[now]-1];
for(int i=size[now];i>=1;i--) f[now][i]=max(f[now][i],f[now][i-1]);
} int main()
{
scanf("%lld%lld",&n,&m);
memset(f,-0x3f,sizeof(f));
for(i=1;i<n;i++)
{
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
dfs(1,0);
printf("%lld",f[1][m]);
}

(话说这道题作为一道连数据范围都没有的题,会爆int是不是有点过分啊啊啊啊啊 (ノ>д<)ノ彡┻━┻

P3177 [HAOI2015]树上染色的更多相关文章

  1. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  2. Luogu P3177 [HAOI2015]树上染色

    一道有机结合了计数和贪心这一DP两大考点的神仙题,不得不说做法是很玄妙. 首先我们很容易想到DP,设\(f_{i,j}\)表示在以\(i\)为根节点的子树中选\(j\)个黑色节点的最大收益值. 然后我 ...

  3. 洛谷 P3177 [HAOI2015]树上染色

    题目链接 题目描述 有一棵点数为 \(N\) 的树,树边有边权.给你一个在 \(0~ N\) 之内的正整数 \(K\) ,你要在这棵树中选择 \(K\)个点,将其染成黑色,并将其他 的\(N-K\)个 ...

  4. 【洛谷】P3177 [HAOI2015]树上染色

    懒得复制题面了直接传送门吧 分析 直接求点与点之间的距离感觉不是很好求,所以我们考虑换一个求法. 瞄了一眼题解 距离跟路径上边的长度有关,所以我们直接来看每一条边的贡献吧(这谁想得到啊) 对于每一条边 ...

  5. 洛谷P3177 [HAOI2015]树上染色(树形dp)

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

  6. 洛谷P3177 [HAOI2015]树上染色(树上背包)

    题意 题目链接 Sol 比较套路吧,设\(f[i][j]\)表示以\(i\)为根的子树中选了\(j\)个黑点对答案的贡献 然后考虑每条边的贡献,边的两边的答案都是可以算出来的 转移的时候背包一下. # ...

  7. BZOJ 4033: [HAOI2015]树上染色题解

    BZOJ 4033: [HAOI2015]树上染色题解(树形dp) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327400 原题地址: BZOJ 403 ...

  8. bzoj 4033: [HAOI2015]树上染色 [树形DP]

    4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...

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

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

随机推荐

  1. .NET MVC自定义Html辅助方法

    using System;using System.Web.Mvc;using System.Web.Routing; namespace MvcTest2.Helpers{ public stati ...

  2. 四:SpringCloud-Hystrix

    八:Hystrix断路器 1. 概述 1.1 分布式系统面临的问题 ==复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.== 上图中的请求需要调用A, P, H ...

  3. 从MySQL到ORM(二):MySQL基础

    一.基本概念 1.数据库: 数据库(DataBase)就是一个存储数据的仓库,为了方便数据的存储和管理,它将数据按照特定的规律存储在磁盘上.通过数据库管理系统,可以有效的组织和管理存储在数据库中的数据 ...

  4. Cookie介绍

    1.Http协议与Cookie Cookie(小量信息)是HTTP协议指定的!先由服务器保存Cookie到浏览器,而下次浏览器请求服务器时把上一次请求得到Cookie再归还给服务器 由服务器创建保存到 ...

  5. LeetCode GrayCode

    class Solution { public: vector<int> grayCode(int n) { vector<int> res; res.push_back(); ...

  6. python学习之老男孩python全栈第九期_day022知识点总结——初识面向对象

    一. 面向对象的引入# 人狗大战 def person(name,HP,aggr,sex): person = { 'name':name, # 昵称 'HP':HP, # 生命值 'aggr':ag ...

  7. DOM基础操作实战代码

    对于已经讲解给大家的DOM实战,我今天给大家几个实战代码,可以让大家加深对此的理解! 1.用DOM动态生成这样一个结构: <div class=”example”> <p class ...

  8. BZOJ2656 [Zjoi2012]数列

    Description 小白和小蓝在一起上数学课,下课后老师留了一道作业,求下面这个数列的通项公式: $$\begin{aligned}A_0 &= 0\\A_1 &= 1\\A_{2 ...

  9. 关于java赋值运算的一个小例子

    直接贴代码,这个也是做题目中遇见的,觉得很好奇,查了一波,然后自己编写代码看了一下,果真如此,哈哈哈...... public class 关于Boolean的赋值运算 { public static ...

  10. drupal 开发笔记

    “以前我在开发Java项目的时候,都需要自己设计数据库表结构,数据库表结构的设计关系到一个人开发技能的高低,而在Drupal里面,我们通常是不需要设计数据库表结构,我们要做的是创建新的内容类型,然后为 ...