树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案
Aspirations:没有结果,没有成绩,acm是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力。
————————————————————————————————————————————————
Background:F. Niyaz and Small Degrees http://codeforces.com/contest/1119/problem/F
这道题目是一道高阶的树形DP的题目,我之前并没有涉及到这类题目。
已经有的基础:DP中的01背包。
特点:看到的树形DP的题解大部分都有DFS模块;状态转移方程自然不必再提。
解决思路:先看官方题解,由于这道题目本身相对高阶,所以我打算从树形DP裸题入手
{
敲门砖:二叉苹果树 https://www.luogu.org/problemnew/show/P2015
这道题目希望我们保留Q根树枝,使得树枝上的苹果数总和最大。
定义f[who][quantity]为who分叉点上保留quantity根树枝的时候,所能拥有的最大苹果数——连接边的权重和。
状态转移方程:f[who][quantity] = max( f[who][quantity], f[who][quantity-variable-1] + f[whose_son][variable] ) ;
和这道题的题解的状态转移方程进行比对:f[u][i]=max(f[u][i],f[u][i−j−1]+f[v][j]+w)
嗯,漏掉了和子节点相连边的权重。所以状态转移方程是:
f[who][quantity] = max( f[who][quantity], f[who][quantity-variable-1] + f[whose_son][variable] + e[now].w) ;
接下来写代码遇到的问题:
1. quantity的定义要明确:是这个点所能连接的所有树枝数(直接或者间接),那么我需要知道子树上有几根树枝,
所以,在当前位置DP之前,需要对子节点进行一次DFS,确定子节点的有几根和它相连的树枝。
注意,当前点的树枝数=子节点树枝数之和+子节点之和,因为要和子节点相连也需要一根树枝。
我在这里定义了sum数组来记录节点对应的树枝数。
2. whose_son不能是父节点,不然在语义上是不通的,而且这样DFS也不可能会结束。
3. 内层循环,分配给子节点的variable应该是 min(quantity-1,sum[whose_sum]) , 因为至少还需要保留一根树枝和子节点相连,再次注意不要漏掉连接边的权值。
4. 这个是前几次交代码之后的错误:输入一条边之后我调用了两次add(a,b,c), 但是一次add里面已经做了两个完整的加边操作了。话说为什么会出现tle和re呢?
re和tle我是真的的想不明白,但是wa是有接下来几种情况:
(1)sum[who] += (sum[whose_son] + 1); 错误写法:sum[who] = sum[whose_son] + 1; 这样不能获取真实的直接或者间接相连的总枝条数,当然,如果
sum[who] += (sum[whose_son] + 1) 配合 调用了两次add(a,b,c)又是另外一个错误了,枝条数过度计算。
(2)请观察这段DP:quantity>0是对的,因为如果who点连接的枝条数是0,那么它能保留的苹果数就是初值0,无需更新;
但是var必须>=0,因为var等于0只是意味着子节点不能有多余的枝条,但是这不意味着var=0没有意义,实际上它的意义在于当前父节点与子节点保持连通,
联通的这条边的权值还是会算进去的,少年,看到f[who][quantity-var-1]吗?里面var是0,但是还有一个-1,代表了父节点和子节点的连通。
for(quantity = min(Q,sum[who]);quantity>;--quantity)
{
for(var = min(quantity-,sum[whose_son]);var>=;--var)
{
f[who][quantity] = max(f[who][quantity],f[who][quantity-var-]+f[whose_son][var]+mp[who][i].w);
}
}
完整代码:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
#define sc scanf
#define pt printf
#define maxn 105
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<b;++i)
#define pi acos(-1.0)
#define ull unsigned long long
#define pb push_back
typedef struct ed{
int to;
int w;
}ed;
ed x;
map<int, vector<ed> > mp;
int N,Q;
void add(int a,int b,int c)
{
x.to=b; x.w=c; mp[a].pb(x);
x.to=a; x.w=c; mp[b].pb(x);
}
int f[maxn][maxn],sum[maxn];
void dfs(int who,int pre)
{
rep(i,,(int)mp[who].size())
{
int whose_son = mp[who][i].to;
if(whose_son==pre) continue;
dfs(whose_son,who);
sum[who] += (sum[whose_son] + );
int var, quantity ;
for(quantity = min(Q,sum[who]);quantity;--quantity)
{
for(var = min(quantity-,sum[whose_son]);var>=;--var)
{
f[who][quantity] = max(f[who][quantity],f[who][quantity-var-]+f[whose_son][var]+mp[who][i].w);
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
int a,b,c;
sc("%d%d",&N,&Q);
rep(i,,N-)
{
sc("%d%d%d",&a,&b,&c);
add(a,b,c);
}
memset(f,,sizeof(f)); memset(sum,,sizeof(sum));
dfs(,-);
pt("%d",f[][Q]);
return ;
}
}
树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案的更多相关文章
- CodeForces Global Round 1
CodeForces Global Round 1 CF新的比赛呢(虽然没啥区别)!这种报名的人多的比赛涨分是真的快.... 所以就写下题解吧. A. Parity 太简单了,随便模拟一下就完了. B ...
- Codeforces Global Round 1 (CF1110) (未完结,只有 A-F)
Codeforces Global Round 1 (CF1110) 继续补题.因为看见同学打了这场,而且涨分还不错,所以觉得这套题目可能会比较有意思. 因为下午要开学了,所以恐怕暂时不能把这套题目补 ...
- Codeforces Global Round 2 Solution
这场题目设置有点问题啊,难度:Div.2 A->Div.2 B->Div.2 D->Div.2 C->Div.2 D->Div.1 D-> Div.1 E-> ...
- Codeforces Global Round 1 - D. Jongmah(动态规划)
Problem Codeforces Global Round 1 - D. Jongmah Time Limit: 3000 mSec Problem Description Input Out ...
- Codeforces Global Round 2 部分题解
F.Niyaz and Small Degrees 挺sb的一题,为什么比赛时只过了4个呢 考虑当\(x\)固定的时候怎么做.显然可以树形DP:设\(f_{u,i=0/1}\)表示只考虑\(u\)子树 ...
- Codeforces Global Round 2 题解
Codeforces Global Round 2 题目链接:https://codeforces.com/contest/1119 A. Ilya and a Colorful Walk 题意: 给 ...
- Codeforces Global Round 1 (A-E题解)
Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^( ...
- Codeforces Global Round 3
Codeforces Global Round 3 A. Another One Bites The Dust 有若干个a,有若干个b,有若干个ab.你现在要把这些串拼成一个串,使得任意两个相邻的位置 ...
- 【手抖康复训练1 】Codeforces Global Round 6
[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思 ...
随机推荐
- 【项目 · Wonderland】预则立 && 他山之石
[软 工 实 践 · 团 队 作 业] 预则立&&他山之石 标签:WonderLand Part 0 · 简要目录 Part 1 · 团队计划 Part 2 · 团队访谈 Part 3 ...
- python第三十课--异常(异常对象传递过程)
演示异常对象传递的过程(往上“抛”),并将其解决 def func1(): print('func1...') print(10/0) def func2(): print('func2...') t ...
- Spring-IOC RootBeanDefinition源码分析
GenericBeanDefinition是一站式的标准bean definition,除了具有指定类.可选的构造参数值和属性参数这些其它bean definition一样的特性外,它还具有通过par ...
- Maven单独构建多模块项目中的单个模块
Maven单独构建多模块项目中的单个模块 说明: 1.可能存在的场景,多模块项目没有互相引用,那么此时可以单独构建单个项目,指定到子模块的pom.xml文件即可完成编译. 2.如果多模块项目各自都 ...
- Drools实战系列(三)之eclipse创建工程
web工程和maven工程是目前比较常用的,当然对现在而言,maven工程是开发中最常用的. 两种Drools项目的创建方式,一种是直接创建Drools项目,另一种是基于Maven创建Drools项目 ...
- C#自定义控件开发
自定义控件开发 一般而言,Visual Studio 2005中自带的几十种控件已经足够我们使用了,但是,在一些特殊的需求中,可能需要一些特殊的控件来与用户进行交互,这时,就需要我们自己开发新的.满足 ...
- Docker学习5-Services – 服务(未完待续)
扩展应用程序并启用负载平衡, 为此,必须在分布式应用程序的层次结构中提升一级:服务.在分布式应用程序中,应用程序的不同部分称为“服务”.例如,一个视频共享站点,它可能包含用于将应用程序数据存储在数据库 ...
- JAVA框架 Spring 引入多个配置文件
1.如果配置文件比较长,可以分多个配置文件.有两种方式: 1)在主配置文件加标签<import/> <import resource="jd/com/other/appli ...
- Java中splite的用法与小技巧
在java.lang包中也有String.split()方法,与.net的类似,都是返回是一个字符型数组,但使用过程中还有一些小技巧.如执行:"2|33|4".split(&quo ...
- P2216 [HAOI2007]理想的正方形
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...