博客
关于我
2018 ICPC宁夏Factories 树形dp
阅读量:403 次
发布时间:2019-03-05

本文共 3014 字,大约阅读时间需要 10 分钟。

2018 ICPC宁夏Factories 树形dp

传送门:

题意

给 一 棵 树 , 在 树 中 选 择 k 个 节 点 , 要 求 输 出 最 小 任 意 两 点 距 离 和 。 给一棵树,在树中选择k个节点,要求输出最小任意两点距离和。 k

思路

树 、 选 择 节 点 、 统 计 距 离 − 树 形 d p 。 树、选择节点、统计距离-树形dp。 dp

设 f [ u ] [ i ] 为 以 u 为 根 的 字 树 中 选 择 i 个 节 点 的 贡 献 。 设f[u][i]为以u为根的字树中选择i个节点的贡献。 f[u][i]ui
转 移 方 程 很 容 易 看 出 : 转移方程很容易看出:

f [ u ] [ i + j ] = m i n ( f [ u ] [ i + j ] , f [ u ] [ i ] + f [ v ] [ j ] + e [ i ] . w ∗ j ∗ ( k − j ) ) f[u][i+j]=min(f[u][i+j],f[u][i]+f[v][j]+e[i].w*j*(k-j)) f[u][i+j]=min(f[u][i+j],f[u][i]+f[v][j]+e[i].wj(kj))

e [ i ] . w ∗ j ∗ ( k − j ) 是 统 计 任 意 两 点 距 离 和 的 套 路 公 式 。 e[i].w*j*(k-j)是统计任意两点距离和的套路公式。 e[i].wj(kj)

在 方 程 中 可 以 看 出 , f [ u ] [ i + j ] 是 与 f [ u ] [ i ] 有 关 的 , 所 以 不 能 正 向 转 移 , 而 要 倒 序 转 移 。 在方程中可以看出,f[u][i+j]是与f[u][i]有关的,所以不能正向转移,而要倒序转移。 f[u][i+j]f[u][i]

但 是 倒 序 转 移 中 会 出 现 转 移 值 出 现 被 更 改 的 问 题 。 但是倒序转移中会出现转移值出现被更改的问题。

所 以 需 要 一 个 辅 助 数 组 , 这 也 是 套 路 , 但 是 不 能 m e m s e t , 可 以 手 写 。 所以需要一个辅助数组,这也是套路,但是不能memset,可以手写。 memset

最 后 注 意 r o o t 不 一 定 为 1 , 需 要 记 录 度 即 可 。 最后注意root不一定为1,需要记录度即可。 root1

Code

#include "bits/stdc++.h"using namespace std;typedef long long ll;const int N = 2e5 + 10;int n, k;struct Edge {       int v, next; ll w;}e[N << 1];int head[N << 1], cnt;ll f[N][110]; // 以u为根的子树中选择k个叶子节点ll temp[110];int siz[N], d[N];inline void add(int u, int v, int w) {       e[++cnt].v = v;    e[cnt].w = w;    e[cnt].next = head[u];    head[u] = cnt;}void dfs(int u, int fa) {       if(d[u] == 1) {           siz[u] = 1, f[u][0] = f[u][1] = 0;        return ;    }    siz[u] = 0;    for(int i = 1;i <= k; i++) f[u][i] = 2e18;    for(int i = head[u]; i; i = e[i].next) {           int v = e[i].v;        if(v == fa) continue;        dfs(v, u);        siz[u] += siz[v];        for(int p = 0;p <= min(siz[u], k); p++) temp[p] = 2e18;        for(int p = 0;p <= min(siz[u], k); p++) {               for(int q = 0;q <= siz[v] && p + q <= k; q++) {                   temp[p + q] = min(temp[p + q], f[u][p] + f[v][q] + e[i].w * q * (k - q));            }        }        for(int p = 0;p <= min(siz[u], k); p++) f[u][p] = temp[p];    }}void solve() {       int _; scanf("%d",&_);    int Case = 1;    while(_--) {           scanf("%d%d",&n,&k);        cnt = 0;        for(int i = 1;i <= n; i++) d[i] = 0, siz[i] = 0, head[i] = 0;        for(int i = 1;i < n; i++) {               int u, v; ll w; scanf("%d%d%lld",&u,&v,&w);            add(u, v, w);            add(v, u, w);            d[u]++; d[v]++;        }        printf("Case #%d: ",Case++);        if(n == 2) {               if(k == 2) printf("%lld\n",e[1].w);            else printf("0\n");            continue;        }        for(int i = 1;i <= n; i++) {               if(d[i] > 1) {                   dfs(i, 0);                printf("%lld\n",f[i][k]);                break ;            }        }    }}signed main() {       solve();}

转载地址:http://ofjwz.baihongyu.com/

你可能感兴趣的文章
mac mysql 进程_Mac平台下启动MySQL到完全终止MySQL----终端八步走
查看>>
Mac OS 12.0.1 如何安装柯美287打印机驱动,刷卡打印
查看>>
MangoDB4.0版本的安装与配置
查看>>
Manjaro 24.1 “Xahea” 发布!具有 KDE Plasma 6.1.5、GNOME 46 和最新的内核增强功能
查看>>
mapping文件目录生成修改
查看>>
MapReduce程序依赖的jar包
查看>>
mariadb multi-source replication(mariadb多主复制)
查看>>
MariaDB的简单使用
查看>>
MaterialForm对tab页进行隐藏
查看>>
Member var and Static var.
查看>>
memcached高速缓存学习笔记001---memcached介绍和安装以及基本使用
查看>>
memcached高速缓存学习笔记003---利用JAVA程序操作memcached crud操作
查看>>
Memcached:Node.js 高性能缓存解决方案
查看>>
memcache、redis原理对比
查看>>
memset初始化高维数组为-1/0
查看>>
Metasploit CGI网关接口渗透测试实战
查看>>
Metasploit Web服务器渗透测试实战
查看>>
MFC模态对话框和非模态对话框
查看>>
Moment.js常见用法总结
查看>>
MongoDB出现Error parsing command line: unrecognised option ‘--fork‘ 的解决方法
查看>>