gym102222 G. Factories

地址

题目大意:

给一棵n个点的树,选m个点,这m个点只能在叶子节点上,问着m个点中两两之间到达其余各点的距离和最小值是多少
题解:
任意两点的树上距离和问题应从边的贡献角度考虑。

树形dp
设 f[u][i] 表示以 u 为根的子树中,选了 i 个叶子节点的最优解,状态转移方程为:

f[u][i+j]=min(f[u][i+j],f[u][i]+f[v][j]+w∗j∗(j−m))

其中所加项为子节点和父节点之间的边的贡献

/*
[HAOI2015]树上染色 的弱化版
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T,n,m,cas;
int main(){
for(scanf("%d",&T);T--;){
scanf("%d%d",&n,&m);
vector<vector<pair<int,ll> > >e(n+);
for(int i=,x,y,z;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
e[x].emplace_back(y,z);
e[y].emplace_back(x,z);
}
if(m==){printf("Case #%d: 0\n",++cas);continue;}
if(n==){printf("Case #%d: %lld\n",++cas,e[][].second);continue;}
vector<vector<ll> > f(n+,vector<ll>(m+,1e14));vector<int>siz(n+,);
function<void(int,int)>dfs=[&](int u,int fa)->void{
bool leaf=;
f[u][]=;
for(auto t:e[u]){
int v=t.first;ll w=t.second;
if(v==fa) continue;
leaf=;
dfs(v,u);
for(int i=min(siz[u],m);~i;i--){
for(int j=min(siz[v],m-i);~j;j--){
f[u][i+j]=min(f[u][i+j],f[u][i]+f[v][j]+w*(m-j)*j);
}
}
siz[u]+=siz[v];
}
if(leaf){f[u][]=;siz[u]=;}
};
int rt=;
for(int i=;i<=n;i++) if(e[i].size()>){rt=i;break;}
dfs(rt,);
printf("Case #%d: %lld\n",++cas,f[rt][m]);
}
return ;
}

第二版

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+;
const int M=N<<;
const int Kn=;
typedef long long ll;
int T,n,k,cas;
int tot,to[M],nxt[M],head[N],ind[N],siz[N];ll val[M];bool vis[N];
ll f[N][Kn];
inline void add(int x,int y,ll z){
ind[x]++;to[++tot]=y;val[tot]=z;nxt[tot]=head[x];head[x]=tot;
}
void dfs(int u,int fa){
for(int l=head[u];l;l=nxt[l]){
int v=to[l];ll w=val[l];
if(v==fa) continue;
dfs(v,u);
siz[u]+=siz[v];
for(int i=min(siz[u],k);i;i--){
for(int j=,re=min(siz[v],i);j<=re;j++){
f[u][i]=min(f[u][i],f[u][i-j]+f[v][j]+w*(k-j)*j);
}
}
}
};
void init_dp(){
for(int i=;i<=n;i++){
f[i][]=;
for(int j=;j<=k;j++) f[i][j]=1e17;
if(ind[i]==) siz[i]=,f[i][]=;
}
}
inline void Clear(){
tot=;
memset(ind,,sizeof ind);
memset(siz,,sizeof siz);
memset(head,,sizeof head);
}
int main(){
for(scanf("%d",&T);T--;Clear()){
scanf("%d%d",&n,&k);
for(int i=,x,y,z;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
int rt=;
for(int i=;i<=n;i++) if(ind[i]>){rt=i;break;}
init_dp();
dfs(rt,);
printf("Case #%d: %lld\n",++cas,f[rt][k]);
}
return ;
}

gym102222 G. Factories的更多相关文章

  1. modern-cpp-features

    C++17/14/11 Overview Many of these descriptions and examples come from various resources (see Acknow ...

  2. 2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest

    目录 Contest Info Solutions A. Maximum Element In A Stack B. Rolling The Polygon C. Caesar Cipherq D. ...

  3. Storyboards Tutorial 03

    这一节主要介绍segues,static table view cells 和 Add Player screen 以及 a game picker screen. Introducing Segue ...

  4. 文件图标SVG

    ​<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink ...

  5. 【银川网络赛G】Factories

    题目大意:给定一棵 N 个节点的树,边有边权,选定 M 个叶子节点,使得任意两个叶子节点的树上距离之和最小,求最小值是多少. 题解:任意两点的树上距离和问题应从边的贡献角度考虑. 设 \(f[u][i ...

  6. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库 ...

  7. CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)

    ---恢复内容开始--- CentOS 6.6 升级GCC G++ (当前最新GCC/G++版本为v6.1.0) 没有便捷方式, yum update....   yum install 或者 添加y ...

  8. Linux deepin 下sublimes配置g++ openGL

    参考 :http://blog.csdn.net/u010129448/article/details/47754623 ubuntu 下gnome只要将代码中deepin-terminal改为gno ...

  9. [翻译svg教程]svg 中的g元素

    svg 中的<g>元素用来组织svg元素.如果一组svg元素被g元素包裹了,你可以通过对g元素进行变换(transform),被g元素包裹的元素也将被变换,就好这些被svg包裹的元素是一个 ...

随机推荐

  1. OpenGL学习 (一) - 简单窗口绘制

    一.OpenGL 简介 OpenGL 本质: OpenGL(Open Graphics Library),通常可以认为是API,其包含了一系列可以操作图形.图像的函数.但深究下来,它是由Khronos ...

  2. VS2019 Nuget找不到包的问题处理

    VS不记得改了什么设置之后,发现找不到EF 解决办法 1.点击右侧的设置按钮 2.弹出窗中左侧树形结构选择“程序包源”,再点击右上方的添加按钮 输入一下信息:https://www.nuget.org ...

  3. [转]js获取iframe通过url传递的参数

    1.前言 获取iframe的url路径:window.parent.document.getElementById("your-iframe-id").contentWindow. ...

  4. [转发] SAP EPIC 银企直连+TRM资金管理

    事务代码:EPIC_PROC 电子支付集成 收款; 付款; 付款审批; 银行回单(下载,创建,修改,辩识,认领); 查询账户余额; 查询交易明细; BADI增强; VA虚拟账户客户回单自动辨识; .. ...

  5. FineReport连接ApacheKylin

    1.前言 Apache Kylin™是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc. 开发并贡献至开源社区.它能在 ...

  6. Java虚拟机是怎么new的对象?

    本文涉及:Java中的new命令之后发生的事 类加载检查 java虚拟机在遇到一条 new 指令时,首先会检查是否能在常量池中定位到这个类的符号引用,并且是否已被加载过.解析和初始化过.如果没有,那必 ...

  7. Matlab中介者模式

    中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护.想象一个乱糟糟的开发小组的工 ...

  8. 【转载】C#中ArrayList集合类使用Add方法添加元素

    ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,因此使用Ar ...

  9. elasticsearch基础查询

    Es基础数据类型 string 字符串类型,es中最常用的类型,官方文档 比较重要的参数: index分析 analyzed(默认) not_analyzed no store存储 true 独立存储 ...

  10. mysql 的逻辑架构 与 存储引擎的介绍

    mysql 的逻辑架构分为三层: 最上层的服务大多数基于网络的客户端.服务器的工具或者服务都有类似的架构,比如连接处理,授权认证.安全等 第二层架构:mysql的核心服务功能都在这一层,包括查询解析, ...