题意:给你一棵 nnn 个节点的树找出 kkk 个不同的点 a1,a2,⋯,aka_1,a_2,\cdots,a_ka1​,a2​,⋯,ak​,
使得 ∑i=1k−1dis(ai,ai+1)\sum\limits_{i=1}^{k-1} dis(a_i,a_{i+1})i=1∑k−1​dis(ai​,ai+1​) 最小。

首先有个容易想到的性质:这 kkk 个点一定是相邻的,那么选 kkk 个点可以看成选 k−1k-1k−1 条相连的边。

但关键是我们不是要算一个环的长度,而是一条路径的长度,也就是说不用算从终点再走回到起点的距离,事情就变得麻烦起来。

用树形 dp 求解:设 dp(i,j,0/1/2)dp(i,j,0/1/2)dp(i,j,0/1/2) 表示在 iii 子树中,选出 jjj 条边的方案数。

其中第 333 维是 000 表示这条路径的两个端点都在根节点 iii 上;第 333 维是 111 表示这条路径的两个端点一个在根节点 iii 上,另一个在 iii 的子树内;第 333 维是 222 表示这条路径的两个端点都在 iii 的子树内,但是这条路径经过 iii。

那么答案就是 min⁡i=1ndp(i,k−1,0/1)\min\limits_{i=1}^n dp(i,k-1,0/1)i=1minn​dp(i,k−1,0/1)。

然后转移也比较明显,主要是这个时间复杂度的证明。

证法一:

设对于某一个点 uuu,以 uuu 为根的子树大小为 sss,uuu 的儿子的子树大小分别为 s1,s2,⋯,sms_1,s_2,\cdots,s_ms1​,s2​,⋯,sm​。

那么在 uuu 节点的时间是:

s1+s1∗s2+(s1+s2)s3+(s1+s2+s3)s4+⋯+(∑i=1m−1si)sm≈s1∗s2+(s1+s2)s3+(s1+s2+s3)s4+⋯+(∑i=1m−1si)sm<2(s1∗s2+(s1+s2)s3+(s1+s2+s3)s4+⋯+(∑i=1m−1si)sm)=s1(s2+s3+⋯+sm)+s2(s1+s3+s4+⋯+sm)+s3(s1+s2+s4+⋯+sm)=s1(s−s1−1)+s2(s−s2−1)+s3(s−s3−1)+⋯+sm(s−sm−1)=s(s1+⋯+sm)−(s12+s22+⋯−sm2)−(s1+s2+⋯+sm)<s(s1+⋯+sm)−(s12+s22+⋯−sm2)=s(s−1)−(s12+s22+⋯−sm2)<s2−s12−s22−⋯−sm2\begin{aligned} &s_1+s_1*s_2+(s_1+s_2)s_3+(s_1+s_2+s_3)s_4+\cdots+\left(\sum_{i=1}^{m-1}s_i\right)s_m\\ \approx&s_1*s_2+(s_1+s_2)s_3+(s_1+s_2+s_3)s_4+\cdots+\left(\sum_{i=1}^{m-1}s_i\right)s_m\\ <&2\left(s_1*s_2+(s_1+s_2)s_3+(s_1+s_2+s_3)s_4+\cdots+\left(\sum_{i=1}^{m-1}s_i\right)s_m\right)\\ =&s_1(s_2+s_3+\cdots+s_m)+s_2(s_1+s_3+s_4+\cdots+s_m)+s_3(s_1+s_2+s_4+\cdots+s_m)\\ =&s_1(s-s_1-1)+s_2(s-s_2-1)+s_3(s-s_3-1)+\cdots+s_m(s-s_m-1)\\ =&s(s_1+\cdots+s_m)-(s_1^2+s_2^2+\cdots-s_m^2)-(s_1+s_2+\cdots+s_m) <&s(s_1+\cdots+s_m)-(s_1^2+s_2^2+\cdots-s_m^2)\\ =&s(s-1)-(s_1^2+s_2^2+\cdots-s_m^2)\\ <&s^2-s_1^2-s_2^2-\cdots-s_m^2 \end{aligned}≈<====<​s1​+s1​∗s2​+(s1​+s2​)s3​+(s1​+s2​+s3​)s4​+⋯+(i=1∑m−1​si​)sm​s1​∗s2​+(s1​+s2​)s3​+(s1​+s2​+s3​)s4​+⋯+(i=1∑m−1​si​)sm​2(s1​∗s2​+(s1​+s2​)s3​+(s1​+s2​+s3​)s4​+⋯+(i=1∑m−1​si​)sm​)s1​(s2​+s3​+⋯+sm​)+s2​(s1​+s3​+s4​+⋯+sm​)+s3​(s1​+s2​+s4​+⋯+sm​)s1​(s−s1​−1)+s2​(s−s2​−1)+s3​(s−s3​−1)+⋯+sm​(s−sm​−1)s(s1​+⋯+sm​)−(s12​+s22​+⋯−sm2​)−(s1​+s2​+⋯+sm​)<s(s−1)−(s12​+s22​+⋯−sm2​)s2−s12​−s22​−⋯−sm2​​s(s1​+⋯+sm​)−(s12​+s22​+⋯−sm2​)​

然后每两层相消,最后总时间复杂度就是根所代表的子树的大小的平方,即 O(n2)O(n^2)O(n2)。

证法二:

dp 的实质可以看做枚举树中的点对 (u,v)(u,v)(u,v),然后当且仅当存在某一个 rootrootroot,使得 uuu 和 vvv 分别在 rootrootroot 的两个儿子的子树中。显然,对于每一个点对 (u,v)(u,v)(u,v),有且仅有一个 root=lca⁡(u,v)root=\operatorname{lca}(u,v)root=lca(u,v)。所以总时间复杂度是 O(n2)O(n^2)O(n2)。

代码如下:

#include<bits/stdc++.h>#define N 3010
#define ll long long
#define INF 0x7fffffffusing namespace std;int n,k,size[N];
int cnt,head[N],nxt[N<<1],to[N<<1];
ll w[N<<1],dp[N][N][3];
//dp[0]:根进根出
//dp[1]:根进子树内出
//dp[2]:子树内进子树内出(经过根) void adde(int u,int v,ll wi)
{to[++cnt]=v;w[cnt]=wi;nxt[cnt]=head[u];head[u]=cnt;
}void dfs(int u,int fa)
{size[u]=1;dp[u][0][0]=dp[u][0][1]=0;for(int i=head[u];i;i=nxt[i]){int v=to[i];if(v==fa) continue;dfs(v,u);for(int j=size[u]-1;j>=0;j--){for(int k=size[v]-1;k>=0;k--){dp[u][j+k+1][0]=min(dp[u][j+k+1][0],dp[u][j][0]+dp[v][k][0]+w[i]*2);dp[u][j+k+1][1]=min(dp[u][j+k+1][1],min(dp[u][j][0]+dp[v][k][1]+w[i],dp[u][j][1]+dp[v][k][0]+w[i]*2));dp[u][j+k+1][2]=min(dp[u][j+k+1][2],min(dp[u][j][0]+dp[v][k][2]+w[i]*2,min(dp[u][j][1]+dp[v][k][1]+w[i],dp[u][j][2]+dp[v][k][0]+w[i]*2)));}}size[u]+=size[v];}
}int main()
{memset(dp,127,sizeof(dp));scanf("%d%d",&n,&k);for(int i=1;i<n;i++){int u,v;ll w;scanf("%d%d%lld",&u,&v,&w);adde(u,v,w),adde(v,u,w);}dfs(1,0);ll ans=INF;for(int i=1;i<=n;i++)ans=min(ans,min(dp[i][k-1][1],dp[i][k-1][2]));printf("%lld\n",ans);return 0;
}

【BZOJ4987】Tree(树形dp)相关推荐

  1. 2021牛客多校4 - Rebuild Tree(树形dp)

    题目链接:点击查看 题目大意:给出一棵 nnn 个节点的树,现在可以删掉 kkk 条边,然后加上 kkk 条边,问有多少种方案使得操作后 nnn 个点仍然是一棵树 题目分析:原树删掉 kkk 条边后会 ...

  2. 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: ...

  3. HDU 5834 Magic boy Bi Luo with his excited tree 树形DP

    Magic boy Bi Luo with his excited tree 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5834 Descript ...

  4. BZOJ.3227.[SDOI2008]红黑树tree(树形DP 思路)

    BZOJ orz MilkyWay天天做sxt! 首先可以树形DP:\(f[i][j][0/1]\)表示\(i\)个点的子树中,黑高度为\(j\),根节点为红/黑节点的最小红节点数(最大同理). 转移 ...

  5. LiberOJ #6210. 「美团 CodeM 决赛」tree 树形DP

    题目链接:点这里 题解: 需要证明,所求的路径一定是全部权值都为1或者,路径上权值至多有一个为2其余为1且权值2在路径中央. 然后树形DP 设定dp[i][0/1] 以1为根的情况下,以i 节点下子树 ...

  6. Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp

    链接: http://codeforces.com/contest/462/problem/D 题意: 给定n个点的树, 0为根,下面n-1行表示每个点的父节点 最后一行n个数 表示每个点的颜色,0为 ...

  7. VK Cup 2012 Round 1 D. Distance in Tree (树形dp)

    题目:http://codeforces.com/problemset/problem/161/D 题意:给你一棵树,问你两点之间的距离正好等于k的有多少个 思路:这个题目的内存限制首先大一倍,他有5 ...

  8. ARC101E Ribbons on Tree 树形dp 容斥

    题目链接 题意: 给你一棵nnn个点的树,nnn是偶数,把这些点分成n2\frac{n}{2}2n​个点对,每个点对会把路径上的所有边覆盖,问你每条边至少覆盖一次有多少种配对方式.n<=5000 ...

  9. A. Parsa‘s Humongous Tree(树形DP + 贪心)

    Problem - 1528A - Codeforces 两个玩家正在玩一个游戏.他们有一个整数1,2,...,n的排列组合(排列组合是一个数组,其中从1到n的每个元素正好出现一次).这个排列组合没有 ...

  10. 根号均摊 ---- E. Xenia and Tree(树形dp + 暴力根号均摊)

    题目大意 题目大意: 你有一颗树:树开始时候1号点是红色的 现在就是你有两次操作: 1 u 把u点涂成红色 2 u 询问离u点最近红点在哪里? 数据范围是n,m∈[1,1e5]n,m\in[1,1e5 ...

最新文章

  1. php提交字段打印,在隱藏的表單字段中提交的JSON編碼的PHP數組 - 在提交表單的頁面中打印時會產生奇怪的輸出...
  2. 【rnnoise源码分析】rnn_train中的训练模型
  3. 【c++】28.虚析构函数、纯虚函数
  4. 数论基础之快速幂(详细教程)
  5. idea 拉取分支代码
  6. 记录java从左上到右下打印二维数组,从左下到右上打印二维数组
  7. Angular 如何自定义 pipe 管道以及参数传递问题
  8. mysql不同的类的个数_Mysql数据库-SQL优化-统计某种类型的个数
  9. sql怎么撤回update_腾讯SQL“现役运动员”给你的实践小技巧
  10. python爬虫库教程_Python爬虫Selenium库详细教程
  11. linux ss命令查看端口监听情况
  12. 百度智能云人脸库的创建与使用
  13. bm3d算法matlab,BM3D算法实现图像降噪.doc
  14. 软件研发成本构成中的间接成本包括哪些?
  15. 应广单片机规格 应广MCU锂电池充电IC
  16. 阿里云ECS数据迁移到阿里云OSS
  17. 【Scikit-Learn 中文文档】40 数据集加载工具 - 用户指南 | ApacheCN
  18. springboot如何解析邮箱
  19. react +antd 实现时间与选择器的重置事件
  20. 希腊字母的读法[转]

热门文章

  1. 【编程题】【Scratch一级】2019.12 小狗长大记
  2. Android JNI学习-调用第三方SO库
  3. SpringBoot整合redis,启动提示错误信息: An exception was thrown by org.redisson.misc.RedissonPromise$$Lambda$682
  4. android实现开机自动运行程序,Android编程实现应用程序开机自启动的方法
  5. vue+element_ui上传文件,并传递额外参数
  6. U8 8.9 数据库置疑恢复方法
  7. 前端构建工具---parcel基础打包应用示例
  8. 初识solr facet(一)
  9. Linux 之系统美化
  10. zic - 时区编辑器