【问题描述】
传说中的九头龙是一种特别贪吃的动物。虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落。
有一天,有 M 个脑袋的九头龙看到一棵长有 N 个果子的果树,喜出望外,恨不得一口把它全部吃掉。可是必须照顾到每个头,因此它需要把 N 个果子分成 M 组,每组至少有一个果子,让每个头吃一组。
这 M 个脑袋中有一个最大,称为“大头”,是众头之首, 它要吃掉恰好 K 个果子,而且 K 个果子中理所当然地应该包括唯一的一个最大的果子。 果子由 N-1根树枝连接起来,由于果树是一个整体,因此可以从任意一个果子出发沿着树枝“走到”任何一个其他的果子。
对于每段树枝,如果它所连接的两个果子需要由不同的头来吃掉,那么两个头会共同把树枝弄断而把果子分开;如果这两个果子是由同一个头来吃掉,那么这个头会懒得把它弄断而直接把果子连同树枝一起吃掉。当然,吃树枝并不是很舒服的,因此每段树枝都有一个吃下去的“难受值”,而九头龙的难受值就是所有头吃掉的树枝的“难受值”之和。
九头龙希望它的“难受值”尽量小,你能帮它算算吗?
例如图 1 所示的例子中,果树包含 8 个果子,7 段树枝,各段树枝的“难受值”标记在了树枝的旁边。九头龙有两个脑袋,大头需要吃掉 4 个果子,其中必须包含最大的果子。即 N=8,M=2,K=4:
最大的果子大头吃 4 个果子,用实心点标识;小头吃 4 个果子,用空心点标识;九头龙的难受值为 4,因为图中用细边标记的树枝被大头吃掉了。
【输入文件】
输入文件 dragon.in 的第 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<=10 5 ),表示存在一段难受值为 c 的树枝连接果子 a 和果子 b。
【输出文件】
输出文件 dragon.out 仅有一行,包含一个整数,表示在满足“大头”的要求的前提下,九头龙的难受值的最小值。如果无法满足要求,输出-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
【样例输出】
4
【样例说明】
该样例对应于题目描述中的例子。

正解:树形DP

解题报告:

  今天考试T4,居然是NOI原题。

  显然是一道树形DP,但是我们考虑记录的状态是什么:f[0、1][i][j]表示以i为根结点的子树中1号吃了j个并且i不选或者选的最小值。同时记忆化。

  直接分类讨论儿子结点选了多少个,总复杂度O(N^3)。

  代码如下:

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int MAXN = ;
LL inf;
int n,m,k,ecnt;
int first[MAXN],next[MAXN*],to[MAXN*];
int brother[MAXN],son[MAXN],lian[MAXN][MAXN];
bool vis[MAXN];
LL f[][MAXN][MAXN]; inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline void down(int x,int fa){
vis[x]=;
for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(vis[v]) continue;
//printf("%d %d\n",v,brother[v]);
brother[v]=son[x]; son[x]=v; down(v,x);
}
} inline LL dfs(int x,int fa,int remain,int flag){
if(x==) { if(remain==) return ; else return -; }
if(f[flag][x][remain]!=-) return f[flag][x][remain];
LL minl=inf,nowl,nowr,suan;
for(int i=;i<=remain;i++) {
nowl=dfs(brother[x],fa,i,flag);
if(nowl==remain) nowr=-;
else nowr=dfs(son[x],x,remain-i-,);//选 /*if(nowl>=0) {
if(flag==1) { suan=nowl+nowr+lian[fa][x]; } else suan=nowl+nowr;
if(suan<minl) minl=suan; }
*/ if(nowl>= && nowr>=) {
if(flag==) { suan=nowl+nowr+lian[fa][x]; } else suan=nowl+nowr;
minl=min(minl,suan);
}
nowr=dfs(son[x],x,remain-i,);//不选
/*if(nowl>=0) {
if(flag==0 && m==2) suan=nowl+nowr+lian[fa][x]; else suan=nowl+nowr;
minl=min(minl,suan);
}*/
if(nowl>= && nowr>=) {
if(flag== && m==) suan=nowl+nowr+lian[fa][x]; else suan=nowl+nowr;
minl=min(minl,suan);
}
}
//printf("%d %d %d %d\n",x,fa,remain,flag);
if(minl==inf) f[flag][x][remain]=-inf; else f[flag][x][remain]=minl;
return f[flag][x][remain];
} inline void work(){
n=getint(); m=getint(); k=getint(); inf=; for(int i=;i<=;i++) inf*=;
int x,y,z;
for(int i=;i<n;i++) {
x=getint(); y=getint(); z=getint(); lian[x][y]=lian[y][x]=z;
next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y;
next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x;
}
if(m-+k>n) { printf("-1"); return ; }
down(,); memset(f,-,sizeof(f));
dfs(son[],,k-,);
printf("%lld",f[][son[]][k-]);
} int main()
{
work();
return ;
}

codevs1746 贪吃的九头龙的更多相关文章

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

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

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

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

  3. 贪吃的九头龙(tyvj P1523)

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

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

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

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

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

  6. vojis1523 NOI2002 贪吃的九头龙

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

  7. codevs贪吃的九头龙

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

  8. [NOI2002] 贪吃的九头龙

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

  9. Vijos1523 NOI2002 贪吃的九头龙 树形dp

    思路不算很难,但细节处理很麻烦 前面建图.多叉转二叉,以及确定dp处理序列的过程都是套路,dp的状态转移过程以注释的形式阐述 #include <cstdio> #include < ...

随机推荐

  1. maven总结2

    依赖 maven版本:apache-maven-3.1.1    IDE: springsource   默认支持maven集成             若使用的是eclipse,则需要先安装m2ec ...

  2. java 19 -15 File类批量更改文件名的方法

    /* 需求: * 把H:\三国演义下面的视频名称修改为 00?_介绍.avi 思路: A:封装目录 B:获取该目录下所有的文件的File数组 C:遍历该File数组,得到每一个File对象 D:拼接一 ...

  3. ArcGis 获取地理、平面坐标系

                                         ESRI.ArcGIS.Geometry.ISpatialReference spatialReference = spati ...

  4. FusionCharts或其它flash的div图层总是浮在最上层? (转)

    div的图层由div的style中的z-index来决定,z-index是层垂直屏幕的坐标,0最小,越大的话位置越靠上. 由于FusionCharts的图表都放在div中,如果页面还有其他的div,将 ...

  5. ruby on rails gem install pg时无法安装

    gem install pg -v '0.18.2' Building native extensions. This could take a while... ERROR: Error insta ...

  6. [转]redis.conf的配置解析

    # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k => 1000 bytes # 1kb ...

  7. 测试驱动开发实践 - Test-Driven Development(转)

    一.前言 不知道大家有没听过“测试先行的开发”这一说法,作为一种开发实践,在过去进行开发时,一般是先开发用户界面或者是类,然后再在此基础上编写测试. 但在TDD中,首先是进行测试用例的编写,然后再进行 ...

  8. [CareerCup] 12.2 Find the Reason of Crash 找到程序崩溃的原因

    12.2 You are given the source to an application which crashes when it is run. After running it ten t ...

  9. [CareerCup] 13.7 Node Pointer 节点指针

    13.7 Write a method that takes a pointer to a Node structure as a parameter and returns a complete c ...

  10. 20145208 《Java程序设计》第6周学习总结

    20145208 <Java程序设计>第6周学习总结 教材学习内容总结 输入与输出 InputStream与OutputStream 从应用程序角度来看,如果要将数据从来源取出,可以使用输 ...