2018宁夏邀请赛G(DFS,动态规划【VECTOR<PAIR>】)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
vector<pair<int,int>>tree[100010];
ll dp[100010][110];/*dp[u][i]表示u节点为根的子树上选择了i个叶子节点,
会经过u这个子树的边的权值和的最优值。转移方程如下:
dp[u][i]=min( dp[u][i-j]+dp[v][j]+w*j*(k-j) );
v是u的子节点,w是u与v之间边的权值,l*(k-l)表示的是这条边会被经过的次数
(j为从v这个树上过来的叶节点数,k-j为其它地方选择的叶节点数)*/
int siz[100010];
int t,n,k;
void dfs(int u,int f)
{
if(tree[u].size()==1)
{
dp[u][0]=0;
dp[u][1]=0;
siz[u]=1;//记录叶子节点数量
return;
}
siz[u]=0;
dp[u][0]=0;
for(int i=0;i<tree[u].size();i++)
{
int v=tree[u][i].first;//联接点
int w=tree[u][i].second;//权重
if(v==f)
continue;
dfs(v,u);
siz[u]+=siz[v];
dp[u][k]=min(dp[u][k],dp[v][k]);//在v上选了k个叶子
for(int j=min(k,siz[u]);j>=1;j--)//限制j最大为k
{
for(int l=1;l<=min(j,siz[v]);l++)
dp[u][j]=min(dp[u][j],dp[u][j-l]+dp[v][l]+l*(k-l)*w);//状态转移方程
}
}
}
int main()
{
scanf("%d",&t);
for(int tt=1;tt<=t;tt++)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
tree[i].clear();
for(int i=1;i<n;i++)
{
int u,v;
int w;
scanf("%d%d%lld",&u,&v,&w);
tree[u].push_back({v,w});
tree[v].push_back({u,w});
}
printf("Case #%d: ",tt);
if(n==2)
printf("%d\n",(k==2?tree[1][0].second:0));//当且仅当k==2时存在一条路的长度
else
{
int rt=0;
for(int i=1;i<=n;i++)
if(tree[i].size()>1)//找到一个不为叶子节点的节点作根
{
rt=i;
break;
}
for(int i=1;i<=n;i++)
{
dp[i][0]=0;
for(int j=1;j<=k;j++)
dp[i][j]=inf;
}
dfs(rt,0);
printf("%lld\n",dp[rt][k]);
}
}
return 0;
}
using namespace std;
typedef long long ll;
const int MAXN=100005;
const int MAXK=105;
const ll INF=(1LL<<60)-1;
vector<pair<int,int> > e[MAXN];
ll dp[MAXN][MAXK],tmp[MAXK];
int sz[MAXN];
void dfs(int u,int f,int k)
{
if((int)e[u].size()==1)
{
sz[u]=1,dp[u][0]=dp[u][1]=0;
return;
}
sz[u]=0;
for(auto &t:e[u])
{
int v=t.first,c=t.second;
if(v==f)continue;
dfs(v,u,k);
int ts=min(k,sz[u]+sz[v]);
for(int i=0;i<=ts;i++)
tmp[i]=INF;
for(int i=0;i<=sz[u];i++)
for(int j=0;j<=sz[v] && i+j<=ts;j++)
tmp[i+j]=min(tmp[i+j],dp[u][i]+dp[v][j]+j*(k-j)*c);
for(int i=0;i<=ts;i++)
dp[u][i]=tmp[i];
sz[u]=ts;
}
}
int main()
{
int T;
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n-1;i++)
{
int u,w,v;
scanf("%d%d%d",&u,&v,&w);
e[u].push_back({v,w});
e[v].push_back({u,w});
}
printf("Case #%d: ",ca);
if(n==2)printf("%d\n",(k==2 ? e[1][0].second : 0));
else
{
int rt=0;
for(int i=1;i<=n;i++)
if((int)e[i].size()>1)rt=i;
assert(rt);
dfs(rt,0,k);
printf("%lld\n",dp[rt][k]);
}
for(int i=1;i<=n;i++)
e[i].clear();
}
return 0;
}
2018宁夏邀请赛G(DFS,动态规划【VECTOR<PAIR>】)的更多相关文章
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
- “2018宁夏邀请赛 ” 兼 “The 2019 Asia Yinchuan First Round Online Programming”
------------7题弟弟,被各位半小时13题的大佬打惨了(滑稽)---------- 签到题就不写了. F :Moving On (1247ms) 题意:给定大小为N的带 ...
- 2018宁夏邀请赛网赛 I. Reversion Count(java练习题)
题目链接 :https://nanti.jisuanke.com/t/26217 Description: There is a positive integer X, X's reversion c ...
- [ICPC 2018 宁夏邀请赛] A-Maximum Element In A Stack(思维)
>传送门< 前言 辣鸡网络赛,虽然我是个菜鸡,然而好几个队伍十几分钟就AK???我心态那会彻底崩了,后来群里炸了,话题直接上知乎热搜,都是2018ICPC宁夏网络赛原题,这怎么玩,拼手速? ...
- 2018宁夏邀请赛L Continuous Intervals
题目链接:https://nanti.jisuanke.com/t/28412 题意: 给出n个数的序列.问序列中有多少个区间满足,排序完之后任意两个相邻的数之差不大于1. 题解: 用max表示区间最 ...
- 2018宁夏邀请赛K Vertex Covers
题目链接:https://nanti.jisuanke.com/t/28411 题意: 给出n(n<=36)个点的一个图.求点覆盖集数. 题解: 将n个点折半为L和R两部分.对于R内部的边,枚举 ...
- 2018宁夏邀请赛I题 bubble sort(思维题
https://vjudge.net/problem/Gym-102222I 居然补到个防ak,刚开始不知道啥是循环左移右移(只能移一次),不好想.. 题意:以冒泡排序为背景 给你n,k 问在1~n的 ...
- 2018宁夏邀请赛 Continuous Intervals(单调栈 线段树
https://vjudge.net/problem/Gym-102222L 题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1. 题解:对于一个区间 [L,R],记最大值为 m ...
- 2018宁夏邀请赛K题Vertex Covers(高维前缀和 状压 折半
https://vjudge.net/problem/Gym-102222K 题意:给定N点M边的无向图,每个点有点权. 点覆盖表示某个点集S{}覆盖了所有的边,其贡献是S中点权之积. 现在让你求所 ...
随机推荐
- BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊:分块
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 题意: 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆 ...
- javascript中的this值
如何确定this的值 this值会被传递给所有函数,this的值是基于运行时调用函数的上下文. 例如:从全局作用域调用sayFoo函数时,this引用window对象, 当它作为myObject的一 ...
- Myeclipse中集成的SVN的登录名与密码的切换方法
Eclipse的SVN插件Subclipse做得很好,在svn操作方面提供了很强大丰富的功能.但到目前为止,该插件对svn用户的概念极为淡薄,不但不能方便地切换用户,而且一旦用户的帐号.密码保存之后, ...
- docker 安装过程
- HDU5768Lucky7(中国剩余定理+容斥定理)(区间个数统计)
When ?? was born, seven crows flew in and stopped beside him. In its childhood, ?? had been unfortun ...
- PLSQL Developer安装、配置、连接oracle数据库
0.资源准备 1) PLSQL Developer安装包(由于安装包超过10M,无法上传,请自行下载) 2) instantclient_11_2安装包(由于安装包超过10M,无法上传,请自行下载) ...
- Python:模块详解及import本质
转于:http://www.cnblogs.com/itfat/p/7481972.html 博主:东大网管 一.定义: 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能), ...
- js遍历for,forEach, for in,for of
ECMAScript5(es5)有三种for循环 简单for for in forEach ECMAScript6(es6)新增 for of 简单for for是循环的基础语法,也是最常用的循环结构 ...
- PCB设计基础及技巧
一.设计步骤 (1)PCB布局 先放置接口类外设: 根据飞线的接口方向,定位各个模块的方位: 局部模块化(按照一个方向逐个局部化): (2)PCB布线 设置设计规则: 先布过孔(电源.地.长线),防止 ...
- C#设计模式(7)——适配器模式
一.概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 二.模型 三.代码实现 using System; /// 这里以 ...