贪吃的九头龙(tyvj P1523)
T2 .tyvj P1523贪吃的九头龙
描述
传说中的九头龙是一种特别贪吃的动物。虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落。
有一天,有M个脑袋的九头龙看到一棵长有N个果子的果树,喜出望外,恨不得一口把它全部吃掉。可是必须照顾到每个头,因此它需要把N个果子分成M组,每组至少有一个果子,让每个头吃一组。
这M个脑袋中有一个最大,称为“大头”,是众头之首,它要吃掉恰好K个果子,而且K个果子中理所当然地应该包括唯一的一个最大的果子。果子由N-1根树枝连接起来,由于果树是一个整体,因此可以从任意一个果子出发沿着树枝“走到”任何一个其他的果子。
对于每段树枝,如果它所连接的两个果子需要由不同的头来吃掉,那么两个头会共同把树枝弄断而把果子分开;如果这两个果子是由同一个头来吃掉,那么这个头会懒得把它弄断而直接把果子连同树枝一起吃掉。当然,吃树枝并不是很舒服的,因此每段树枝都有一个吃下去的“难受值”,而九头龙的难受值就是所有头吃掉的树枝的“难受值”之和。
九头龙希望它的“难受值”尽量小,你能帮它算算吗?
格式
输入格式
输入的第1行包含三个整数N(1<=N<=300),M(2<=M<=N),K(1<=K<=N)。N个果子依次编号1,2,...,N,且最大的果子的编号总是1。第2行到第N行描述了果树的形态,每行包含三个整数a(1<=a<=N),b(1<=b<=N),c(0<=c<=105),表示存在一段难受值为c的树枝连接果子a和果子b。
输出格式
输出仅有一行,包含一个整数,表示在满足“大头”的要求的前提下,九头龙的难受值的最小值。如果无法满足要求,输出-1。
样例1
样例输入1
8 2 4
1 2 20
1 3 4
1 4 13
2 5 10
2 6 12
3 7 15
3 8 5
样例输出1
4
分析:
爆搜搜了20分
正解:树形DP
题目可以分为m=2和m>2的情况,因为当m>2是,小头一定不会产生难受值,只关心大头就可以,而当m=2时,小头要选择出大头选的k个之外的所有果子,把题目当作两个头来做。
注意事先用左儿子右兄弟表示法转换成一棵二叉树。
fa代表父亲,val是难受值,ch是左儿子和右兄弟。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#define M 310
#define INF 100000000
using namespace std;
int fa[M],val[M][M],ch[M][],f[M][M][],head[M],n,m,k;
struct node
{
int v,pre,t;
};node e[M*];
void add(int i,int x,int y,int z)
{
e[i].v=y;
e[i].t=z;
e[i].pre=head[x];
head[x]=i;
}
void build(int x)
{
for(int i=head[x];i;i=e[i].pre)
if(!fa[e[i].v])
{
fa[e[i].v]=x;
if(!ch[x][])ch[x][]=e[i].v;
else
{
int f=ch[x][];
while(ch[f][])f=ch[f][];
ch[f][]=e[i].v;
}
build(e[i].v);
}
}
int dfs1(int now,int sum,int p)//now是当前节点,sum是大头还有几个没选,p是now的父亲有没有选
{
if(f[now][sum][p]!=-)return f[now][sum][p];
if(now==&&sum>)return INF;
if(now==&&sum==)return ;
int minn=INF;
for(int i=;i<=sum;i++)//大头不选
{
int tot=;
if(p==)tot+=val[now][fa[now]];
tot+=dfs1(ch[now][],i,)+dfs1(ch[now][],sum-i,p);
minn=min(minn,tot);
}
for(int i=;i<sum;i++)//大头选
{
int tot=;
if(p==)tot+=val[now][fa[now]];
tot+=dfs1(ch[now][],i,)+dfs1(ch[now][],sum-i-,p);
minn=min(minn,tot);
}
f[now][sum][p]=minn;
return f[now][sum][p];
}
int dfs2(int now,int sum,int p)//now是当前节点,sum是大头还有几个没选,p是now的父亲有没有选
{
if(f[now][sum][p]!=-)return f[now][sum][p];
if(sum==)return ;
if(now==)return INF;
int minn=INF;
for(int i=;i<=sum;i++)//大头不选
minn=min(minn,dfs2(ch[now][],i,)+dfs2(ch[now][],sum-i,p));
for(int i=;i<sum;i++)//大头选
{
int tot=;
if(p==)tot+=val[now][fa[now]];
tot+=dfs2(ch[now][],i,)+dfs2(ch[now][],sum-i-,p);
minn=min(minn,tot);
}
f[now][sum][p]=minn;
return f[now][sum][p];
}
int main()
{
freopen("jh.in","r",stdin);
memset(f,-,sizeof(f));
scanf("%d%d%d",&n,&m,&k);
if(n-k<m-){printf("-1");return ;}
for(int i=;i<=n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
val[x][y]=val[y][x]=z;
add(i*-,x,y,z);
add(i*,y,x,z);
}
fa[]=;build();
if(m==)//考虑大头小头一起选
{
int ans=INF;
for(int i=;i<k;i++)
ans=min(ans,dfs1(ch[][],i,)+dfs1(ch[][],k-i-,));
printf("%d",ans);
}
else//只考虑选大头的情况
{
int ans=INF;
for(int i=;i<k;i++)
ans=min(ans,dfs2(ch[][],i,)+dfs2(ch[][],k-i-,));
printf("%d",ans);
}
return ;
}
贪吃的九头龙(tyvj P1523)的更多相关文章
- Vijos1523贪吃的九头龙【树形DP】
贪吃的九头龙 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头 ...
- [codevs1746][NOI2002]贪吃的九头龙
[codevs1746][NOI2002]贪吃的九头龙 试题描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是说它出生的时候有九个头,而在成长的过程中,它有时 ...
- Vijos 1523 贪吃的九头龙 【树形DP】
贪吃的九头龙 背景 安徽省芜湖市第二十七中学测试题 NOI 2002 贪吃的九头龙(dragon) Description:OfficialData:OfficialProgram:Converted ...
- [NOI2002]贪吃的九头龙(树形dp)
[NOI2002]贪吃的九头龙 题目背景 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是 说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的 ...
- codevs1746 贪吃的九头龙
[问题描述]传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落.有一 ...
- vojis1523 NOI2002 贪吃的九头龙
描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落. 有一天, ...
- codevs贪吃的九头龙
传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落.有一天,有M 个 ...
- [NOI2002] 贪吃的九头龙
题目类型:树形DP 传送门:>Here< 题意:有一只九头龙要吃了一颗树,给出一棵\(N\)个节点的带边权的树.九头龙有\(M\)个头,其中一个是大头,大头要吃恰好\(K\)个节点,其他头 ...
- vijos p1523 贪吃的九头龙 思考思考再思考,就荒废了4小时
树形DP要有自己的风格,转二叉树是基础,考虑边界最头疼. #include<cstdio> #include<cstring> #include<algorithm> ...
随机推荐
- 172 Factorial Trailing Zeroes 阶乘后的零
给定一个整数 n,返回 n! 结果尾数中零的数量.注意: 你的解决方案应为对数时间复杂度. 详见:https://leetcode.com/problems/factorial-trailing-ze ...
- Oracle中的表空间
表空间是什么? Oracle数据库包含逻辑结构和物理结构. 数据库的物理结构是指构成数据库的一组操作系统文件. 数据库的逻辑结构是指描述数据组织方式的一组逻辑概念及它们之间的关系. 表空间是数据库数据 ...
- web+ admin template,spa管理应用后台,easyui后台正式发布
演示地址:http://admintemplate.webplus.org.cn/ v1.0 (2016/7/27) 扁平化风格 全屏支持 后台管理不使用iframe,全ajax开发 权限管理 商品管 ...
- 2017广东工业大学程序设计竞赛决赛 G 等凹数字
题意: Description 定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如54 ...
- 微信小程序组件解读和分析:十四、slider滑动选择器
slider滑动选择器组件说明: 滑动选择器. slider滑动选择器示例代码运行效果如下: 下面是WXML代码: [XML] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 ...
- iOS Programming Auto Layout: Programmatic Constraints 自动布局:通过编程限制
iOS Programming Auto Layout: Programmatic Constraints 1. However, if your views are created in co ...
- Python基础教程 读书笔记(2)第二章 列表和元组
2.1序列概览 列表和元组的主要区别在于,列表可以修改,元组则不能.也就是说如果要根据要求来添加元素,那么列表可能会更好用;而出于某些原因,序列不能修改的时候,使用元组则更为合适.使用后者的理由通常是 ...
- 【经验分享】IMX6开发板编译问题及解决方法
本文转自迅为IMX6开发板售后讨论群,分享给大家~物理主机 win10 64 位专业版.虚拟机 VM12 Pro.开发环境采用迅为提供的开发环境:Ubuntu12.04.2 .镜像采用最新的:iTOP ...
- python远程控制电脑
python拥有大量的第三方库,且语法简单.今天老杨就用python实现远程控制电脑 所谓,谋定而后动,在实现任何一个需求之前,我们需要先分析,捋清楚一个思路,远程控制电脑,无非就是接收远程的命令 ...
- Pycharm 设置python文件自动生成头部信息模板
设置头部信息路径: 打开File—Settings—Editor—File and Code Templates—Python Script 输入要自动生成的头部信息模板 这样,新建py文件就会自动生 ...