★★☆   输入文件:haoi2015_t1.in   输出文件:haoi2015_t1.out   简单对比
                    时间限制:1 s   内存限制:256 MB

【题目描述】

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

题解:

  这是一道树形DP,考虑对于每一条边,它对答案的贡献值=两端的黑点个数乘积*边权+两端白点个数乘积*边权。

  令f[i][j]表示以i为根的子树中,有j个黑点的最大收益。对于某一个节点x及其某一儿子y,考虑x与y的连边对答案的贡献,我们可以先枚举x中的黑点个数,再枚举y的黑点个数,用类似01背包来转移。

 /**************************************************************
Problem: 4033
User: __abcdef__
Language: C++
Result: Accepted
Time:6824 ms
Memory:32932 kb
****************************************************************/ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long LL;
const LL inf=1e15,maxn=;
LL N,K;
vector<LL> to[maxn],cost[maxn];
LL fa[maxn],f[maxn][maxn],siz[maxn];
inline void dfs(LL x,LL fath){
fa[x]=fath; siz[x]=;
for(int i=;i<to[x].size();i++){
LL y=to[x][i];
if(y!=fath){
dfs(y,x);
siz[x]+=siz[y];
}
}
} inline void calc(LL x){//计算以x为根的情况
f[x][]=; f[x][]=;
if(siz[x]==) return ;//叶子节点
for(int i=;i<to[x].size();i++){//枚举子树
LL y=to[x][i],val=cost[x][i];
if(y!=fa[x]){
calc(y);
for(int tot=min(K,siz[x]);tot>=;tot--){//枚举以x为根的子树中有几个黑点
for(int j=;j<=min(siz[y],K)&&j<=tot;j++){//这个子树中有多少黑点
LL ans1=(LL)j*(K-(LL)j)*val;
LL ans2=(siz[y]-(LL)j)*(N-K-(siz[y]-(LL)j))*val;
LL tmp=f[y][j]+ans1+ans2;
f[x][tot]=max(f[x][tot],f[x][tot-j]+tmp);
}
}
}
}
} int main(){
scanf("%lld%lld",&N,&K);
for(int i=;i<=N-;i++){
LL u,v,c;
scanf("%lld%lld%lld",&u,&v,&c);
to[u].push_back(v); cost[u].push_back(c);
to[v].push_back(u); cost[v].push_back(c);
}
for(int i=;i<=N;i++){
for(int j=;j<=N;j++){
f[i][j]=-inf;
}
}
dfs(,-);
calc();
printf("%lld\n",f[][K]);
return ;
}

cogs 1962. [HAOI2015]树上染色的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. BZOJ_4033_[HAOI2015]树上染色_树形DP

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

  7. BZOJ 4033[HAOI2015] 树上染色(树形DP)

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

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

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

  9. [HAOI2015]树上染色(树上dp)

    [HAOI2015]树上染色 这种要算点对之间路径的长度和的题,难以统计每个点的贡献.这个时候一般考虑算每一条边贡献了哪些点对. 知道这个套路以后,那么这题就很好做了. 状态:设\(dp[u][i]\ ...

随机推荐

  1. iOS-Foundation框架—结构体(转载)

    一.基本知识 Foundation—基础框架.框架中包含了很多开发中常用的数据类型,如结构体,枚举,类等,是其他ios框架的基础. 如果要想使用foundation框架中的数据类型,那么包含它的主头文 ...

  2. 缓存服务,还未创建完缓存时, 需要更改图层名称、服务名称、数据源位置、mxd名称等

    缓存服务,还未创建完缓存时, 需要更改图层名称.服务名称.数据源位置.mxd名称等.已经创建好的缓存还可以再用吗? 测试后可以, 注意:新服务相对旧服务,符号样式没有改变,切片方案没有变化. 测试步骤 ...

  3. java.io.File实战

    There are many things that can go wrong: A class works in Unix but doesn't on Windows (or vice versa ...

  4. sql server 存储机制

    1.区段 区段(extent)是用来为表和索引分配空间的基本存储单元.它由8个连续的64KB数据页组成. 基于区段(而不是实际使用空间)分配空间的概念的要点: 一旦区段已满,那么下一记录将要占据的空间 ...

  5. 【剑指offer】用两个栈实现队列

    一.题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 二.思路: 两个栈A,B,A负责进栈,B负责出栈,进栈很容易,A中添加即可,出栈需要从B里出,所以要先 ...

  6. PHP消息队列实现及应用_慕课网学习

    https://blog.csdn.net/d_g_h/article/details/79643714 https://blog.csdn.net/tTU1EvLDeLFq5btqiK/articl ...

  7. mysql 备份脚本

    #!/bin/bash cd /data/backup/www /usr/bin/mysqldump -u root --password=root www > /data/backup/www ...

  8. [LeetCode] 496. Next Greater Element I_Easy tag: Stack

    You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...

  9. testng入门教程2用TestNG编写测试及执行测试

    编写TestNG测试基本上包括以下步骤: 测试和编写业务逻辑,在代码中插入TestNG的注解.. 添加一个testng.xml文件或build.xml中在测试信息(例如类名,您想要运行的组,等..) ...

  10. linq判断一个枚举的Name是否存在

    比如,枚举如下: [Serializable] public enum PayType : int { /// <summary> /// AAA /// </summary> ...