【bzoj4987】Tree 树形dp
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
Sol
首先显然这些点是树中的一个联通子块。这个联通子块也是一棵树,而这个联通子块内最优的安排顺序就是让直径只走一遍,其他的边都走两遍。所以我们的treedp是需要围绕直径展开的。我们不妨枚举一个子树内包含了多少个直径上的端点(0,1,2),然后树形背包合并。
设\(f[i][j][k]\)表示以i为根的子树中,有j个选定的点,这些点中直径的端点有k个。那么在合并答案的时候,如果子节点子树的\(k=0\),那么说明子节点子树内的边全都不是直径,所以当前根节点到这个子节点的边长就要经过两次;如果子节点子树的\(k=1\),那么说明子节点子树内有直径的一部分,所以当前根节点到这个子节点的边长也是直径,只用经过一次;如果\(k=2\),那么说明整个直径都在子节点子树内,所以当前根节点到这个子节点的边长需要经过两次。之后我们只需要枚举子树中关键点的个数,枚举两个子树中的k,再加上当前这条边的贡献,就能够完成转移了。
$f[x][a+b+1][c]=min(f[x][a+b+1][c],f[x][a][c-d]+f[to[i]][b][d]+len[i]*(2-(d&1))); $
其中a,b枚举的是子节点关键点的点数,c表示根节点的k,d表示子节点的k,转移的时候枚举这些变量即可。
Code
#include <bits/stdc++.h>
using namespace std;
int hed[3005],to[6005],len[6005],nex[6005],cnt,siz[3005],f[3005][3005][3],n,m,x,y,z,ans=2147483647;
void add(int x,int y,int z){to[++cnt]=y,len[cnt]=z,nex[cnt]=hed[x],hed[x]=cnt;}
void dfs(int x,int fa)
{
siz[x]=1,f[x][0][0]=f[x][0][1]=0;
for(int i=hed[x];i;i=nex[i]) if(to[i]!=fa)
{
dfs(to[i],x);
for(int a=siz[x]-1;~a;a--) for(int b=siz[to[i]]-1;~b;b--) for(int c=2;~c;c--) for(int d=c;~d;d--)
f[x][a+b+1][c]=min(f[x][a+b+1][c],f[x][a][c-d]+f[to[i]][b][d]+len[i]*(2-(d&1)));
siz[x]+=siz[to[i]];
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
memset(f,0x3f,sizeof(f));dfs(1,0);
for(int i=1;i<=n;i++) for(int j=0;j<=2;j++) ans=min(ans,f[i][m-1][j]);
printf("%d\n",ans);
}
【bzoj4987】Tree 树形dp的更多相关文章
- BZOJ4987:Tree(树形DP)
Description 从前有棵树. 找出K个点A1,A2,…,Ak. 使得∑dis(AiAi+1),(1<=i<=K-1)最小. Input 第一行两个正整数n,k,表示数的顶点数和需要 ...
- 熟练剖分(tree) 树形DP
熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...
- 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: ...
- 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 ...
- codeforces 161D Distance in Tree 树形dp
题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...
- hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
/** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...
- 5.10 省选模拟赛 tree 树形dp 逆元
LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...
- Codeforces Round #263 Div.1 B Appleman and Tree --树形DP【转】
题意:给了一棵树以及每个节点的颜色,1代表黑,0代表白,求将这棵树拆成k棵树,使得每棵树恰好有一个黑色节点的方法数 解法:树形DP问题.定义: dp[u][0]表示以u为根的子树对父亲的贡献为0 dp ...
- codeforces Round #263(div2) D. Appleman and Tree 树形dp
题意: 给出一棵树,每个节点都被标记了黑或白色,要求把这棵树的其中k条变切换,划分成k+1棵子树,每颗子树必须有1个黑色节点,求有多少种划分方法. 题解: 树形dp dp[x][0]表示是以x为根的树 ...
- POJ 2486 Apple Tree(树形DP)
题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...
随机推荐
- Three.js导入gltf模型和动画
核心代码 复杂的3D模型一般都是用第三方建模工具生成,然后加载到three中 three官方推荐使用gltf格式的文件,代表编辑器是blender 本文生成了自定义生成了一个blender模型,并且应 ...
- Python Twisted系列教程2:异步编程初探与reactor模式
作者:dave@http://krondo.com/slow-poetry-and-the-apocalypse/ 译者:杨晓伟(采用意译) 这个系列是从这里开始的,欢迎你再次来到这里来.现在我们可 ...
- libevent网络编程汇总
libevent源码剖析: ========================================================== 1.libevent源码剖析一(序) 2.libeve ...
- CBitmap Detach和DeleteObject的关系
注意:当使用完资源后,必须通过调用函数以释放加速器表.位图.光标.图标以及菜单所占的内存资源: 加速器表:DesteoyAcceleratorTable: 位图:DeleteObj ...
- Spring总结十:事务案例
数据库表Account: 导包: <dependencies> <!--测试--> <dependency> <groupId>junit</gr ...
- [luogu3369]普通平衡树(treap模板)
解题关键:treap模板保存. #include<cstdio> #include<cstring> #include<algorithm> #include< ...
- libevent源码深度剖析七
libevent源码深度剖析七 ——事件主循环 张亮 现在我们已经初步了解了libevent的Reactor组件——event_base和事件管理框架,接下来就是libevent事件处理的中心部分 — ...
- php opcode
opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定. 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数. 这些操作数可能是寄存 ...
- swfupload上传文件数量限制之setStats()
使用swfupload仿赶集的图片上传 SWFUpload是一个基于flash与javascript的客户端文件上传组件. handlers.js文件 完成文件入列队(fileQueued) → 完成 ...
- Docker学习笔记_Dockerfile基本知识
Dockerfile由一行行命令语句组成,并支持以#开头的注释行. 1.编写一个Dockerfile文件 创建一个空的Docker工作目录,进入该目录,使用sudo vim Dockerfile指令新 ...