博客
关于我
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/

你可能感兴趣的文章
mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
查看>>
Webpack 基本环境搭建
查看>>
mysql5.7 安装版 表不能输入汉字解决方案
查看>>
MySQL5.7.18主从复制搭建(一主一从)
查看>>
MySQL5.7.19-win64安装启动
查看>>
mysql5.7.19安装图解_mysql5.7.19 winx64解压缩版安装配置教程
查看>>
MySQL5.7.37windows解压版的安装使用
查看>>
mysql5.7免费下载地址
查看>>
mysql5.7命令总结
查看>>
mysql5.7安装
查看>>
mysql5.7性能调优my.ini
查看>>
MySQL5.7新增Performance Schema表
查看>>
Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
查看>>
Webpack 之 basic chunk graph
查看>>
Mysql5.7版本单机版my.cnf配置文件
查看>>
mysql5.7的安装和Navicat的安装
查看>>
mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
查看>>
Mysql8 数据库安装及主从配置 | Spring Cloud 2
查看>>
mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
查看>>
MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
查看>>