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)的更多相关文章

  1. Vijos1523贪吃的九头龙【树形DP】

    贪吃的九头龙 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头 ...

  2. [codevs1746][NOI2002]贪吃的九头龙

    [codevs1746][NOI2002]贪吃的九头龙 试题描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是说它出生的时候有九个头,而在成长的过程中,它有时 ...

  3. Vijos 1523 贪吃的九头龙 【树形DP】

    贪吃的九头龙 背景 安徽省芜湖市第二十七中学测试题 NOI 2002 贪吃的九头龙(dragon) Description:OfficialData:OfficialProgram:Converted ...

  4. [NOI2002]贪吃的九头龙(树形dp)

    [NOI2002]贪吃的九头龙 题目背景 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是 说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的 ...

  5. codevs1746 贪吃的九头龙

    [问题描述]传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落.有一 ...

  6. vojis1523 NOI2002 贪吃的九头龙

    描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落. 有一天, ...

  7. codevs贪吃的九头龙

    传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落.有一天,有M 个 ...

  8. [NOI2002] 贪吃的九头龙

    题目类型:树形DP 传送门:>Here< 题意:有一只九头龙要吃了一颗树,给出一棵\(N\)个节点的带边权的树.九头龙有\(M\)个头,其中一个是大头,大头要吃恰好\(K\)个节点,其他头 ...

  9. vijos p1523 贪吃的九头龙 思考思考再思考,就荒废了4小时

    树形DP要有自己的风格,转二叉树是基础,考虑边界最头疼. #include<cstdio> #include<cstring> #include<algorithm> ...

随机推荐

  1. 16-1 WEB存储基本操作

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  2. 转 PHP编程过程中需要了解的this,self,parent的区别

    {一}PHP中this,self,parent的区别之一this篇 面向对象编程(OOP,Object Oriented Programming)现已经成为编程人员的一项基本技能.利用OOP的思想进行 ...

  3. UML 活动图(转载)

    活动图:用于表示系统中各种活动的次序,它的应用非常广泛,即可用来描述用例的工作流程,也可用来描述类中某个方法的操作行为.常用于表示业务流程,对系统功能建模,强调对象之间的控制流.活动图是由状态图变化而 ...

  4. L 裁纸片 贪心 + 模拟

    https://biancheng.love/contest-ng/index.html#/123/problems 如果只是输出最小的值,那么好办,a升序,b降序,这样是最优的. 但是需要次数,这就 ...

  5. 2556. [NOIP2016]玩具谜题

    [题目描述] 小南有一套可爱的玩具小人,它们各有不同的职业.有一天,这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝国内,有的面朝圈外.如下图: 这时singer告诉小南 ...

  6. Saleae Logic添加NEC IR协议

    一.下载需要用到的代码 Git clone https://github.com/LiveOverflow/NECAnalyzer.git git clone --recursive https:// ...

  7. 重构31-Replace conditional with Polymorphism(多态代替条件)

    多态(Polymorphism)是面向对象编程的基本概念之一.在这里,是指在进行类型检查和执行某些类型操作时,最好将算法封装在类中,并且使用多态来对代码中的调用进行抽象. public class O ...

  8. android 2.2 preview3 编译bug

    平台 as2.2 preview3;   1. 解决方法: 在project.buildgradle 里面设置 // Top-level build file where you can add co ...

  9. iOS中的蓝牙

    iOS中的蓝牙 概述 iOS中提供了4个框架用于实现蓝牙连接 1.GameKit.framework(用法简单) 只能用于iOS设备之间的同个应用内连接,多用于游戏(eg.拳皇,棋牌类),从iOS7开 ...

  10. qt creator转换到 COFF 期间失败: 文件无效或损坏

    转载请注明出处http://www.cnblogs.com/dachen408/p/7226198.html 环境 Qt5.5+Vs2010,删除vs2010安装目录bin下的cvtres.exe解决 ...