Description

从前有棵树。
找出K个点A1,A2,…,Ak。
使得∑dis(AiAi+1),(1<=i<=K-1)最小。
 

Input

第一行两个正整数n,k,表示数的顶点数和需要选出的点个数。
接下来n-l行每行3个非负整数x,y,z,表示从存在一条从x到y权值为z的边。
I<=k<=n。
l<x,y<=n
1<=z<=10^5
n <= 3000
 

Output

一行一个整数,表示最小的距离和。
 

Sample Input

10 7
1 2 35129
2 3 42976
3 4 24497
2 5 83165
1 6 4748
5 7 38311
4 8 70052
3 9 3561
8 10 80238

Sample Output

184524
 
 
首先,为了保证最优,选出的点相邻,而且对于每条边,如果要算上从$a_k$走到$a_1$的话,相当于每条边走了两遍
那么现在不用算$a_k$走到$a_1$,相当于是从这一个联通块里选出一条链去掉它的贡献,其余的边都要被计算两边,那么我们可以转化为选出一些边
考虑树形dp,设$f[i][j][k]$表示在第$i$个点及其子树中选出了$j$条边,$k$表示选边的状态,此时的最小代价
$k=0$表示从当前的根节点遍历一遍子树中选的边再回来,$k=1$,表示遍历完子树就不回来,$k=2$表示从子树中某一个点遍历到根节点再出去又回来到另一个端点
然后不难发现每一个数字代表的状态都能由数值加起来等于它的状态转移而来。比方说状态2,可以看做是由两个状态为1的状态拼起来得到
又发现当前根和子树之间的连边只有在$k=1$时算一遍,其他时候都算两遍
然后树形dp即可
 //minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=;
int head[N],Next[N<<],ver[N<<],edge[N<<],tot;
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
}
int sz[N],f[N][N][],n,m,ans=<<;
void dfs(int u,int fa){
sz[u]=,f[u][][]=f[u][][]=;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa){
dfs(v,u);
for(int j=sz[u]-;~j;--j)
for(int k=sz[v]-;~k;--k)
for(int l=;~l;--l)
for(int m=l;~m;--m)
cmin(f[u][j+k+][l],f[u][j][l-m]+f[v][k][m]+edge[i]*(-(m==)));
sz[u]+=sz[v];
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=,u,v,e;i<n;++i)
u=read(),v=read(),e=read(),add(u,v,e),add(v,u,e);
memset(f,0x3f,sizeof(f));dfs(,);
for(int i=;i<=n;++i) for(int j=;j<=;++j) cmin(ans,f[i][m-][j]);
printf("%d\n",ans);
return ;
}

bzoj4987: Tree(树形dp)的更多相关文章

  1. BZOJ4987:Tree(树形DP)

    Description 从前有棵树. 找出K个点A1,A2,…,Ak. 使得∑dis(AiAi+1),(1<=i<=K-1)最小. Input 第一行两个正整数n,k,表示数的顶点数和需要 ...

  2. 熟练剖分(tree) 树形DP

    熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...

  3. hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)

    题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: ...

  4. CF 461B Appleman and Tree 树形DP

    Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other ...

  5. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

  6. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  7. 5.10 省选模拟赛 tree 树形dp 逆元

    LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...

  8. Codeforces Round #263 Div.1 B Appleman and Tree --树形DP【转】

    题意:给了一棵树以及每个节点的颜色,1代表黑,0代表白,求将这棵树拆成k棵树,使得每棵树恰好有一个黑色节点的方法数 解法:树形DP问题.定义: dp[u][0]表示以u为根的子树对父亲的贡献为0 dp ...

  9. codeforces Round #263(div2) D. Appleman and Tree 树形dp

    题意: 给出一棵树,每个节点都被标记了黑或白色,要求把这棵树的其中k条变切换,划分成k+1棵子树,每颗子树必须有1个黑色节点,求有多少种划分方法. 题解: 树形dp dp[x][0]表示是以x为根的树 ...

  10. POJ 2486 Apple Tree(树形DP)

    题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...

随机推荐

  1. postman工具的应用实战(二)

    在接口测试工具中,最好的应该是soapui,jmeter,postman,但是soapui需要安装和破解,当然也是有破解版的,但是不够灵活,jmeter工具 做接口测试还是性能测试,功能测试,都是一个 ...

  2. CookiesReader

    CookiesReader "use strict"; /** * * @author xgqfrms * @license MIT * @copyright xgqfrms * ...

  3. POJ 2431 Expedition【贪心】

    题意: 卡车每走一个单元消耗一升汽油,中途有加油站,可以进行加油,问能否到达终点,求最少加油次数. 分析: 优先队列+贪心 代码: #include<iostream> #include& ...

  4. [bzoj1324]Exca王者之剑_最小割

    Exca王者之剑 bzoj-1324 题目大意:题目链接. 注释:略. 想法: 最小割经典模型. 所有格子向源点连权值为格子权值的边. 将棋盘黑白染色后白点反转源汇. 如果两个格子相邻那么黑点向白点连 ...

  5. anaconda是个啥?

    Anaconda具有跨平台(win/mac/linux).包管理(类似于pip).环境管理(类似于virtualenv)的特点,因此很适合快速在新的机器上部署Python环境 Anaconda利用工具 ...

  6. dubbo的泛化调用研究

    结论: 泛化调用需要继承一个类,在配置文件里需要明确指出generic=true; 泛化调用在书写provider代码时,变化不大: 泛化调用和普通调用的区别主要在consumer,从‘调用’的表面意 ...

  7. C++ - 库函数优先级队列(priority_queue)输出最小值 代码

    库函数优先级队列(priority_queue)输出最小值 代码 本文地址: http://blog.csdn.net/caroline_wendy 库函数优先级队列(priority_queue)的 ...

  8. C#——await与async实现多线程异步编程

    曾经,我们也许用过Thread.在主线程运行的时候.新开还有一个新线程,来运行新方法. 今天看别人发给我的一段代码的时候发现了一个不认识的await,可是又感觉非常熟悉的样子,感觉是线程那块儿的东西, ...

  9. Lua中..和#运算符的用法

    Lua中..和#运算符的用法 样例 试试以下的样例就明确了在Lua编程语言提供的其它运算符: a = "Hello " b = "World" print(&q ...

  10. 洛谷P2668 斗地主==codevs 4610 斗地主[NOIP 2015 day1 T3]

    P2668 斗地主 326通过 2.6K提交 题目提供者洛谷OnlineJudge 标签搜索/枚举NOIp提高组2015 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 出现未知错误是说梗啊 ...