考试总结T2(接上次整的T1)
首先说一句,树的每个元素的名称的问题,(那个叫jie点的东西)
具体是节点还是结点...baidu百科写的是结点...
本文章将不考虑到底这俩字怎么写...所以两种都可能出现
T2描述:
扶苏翻遍了歌单却没有找到一首歌能做这个题的题目背景,于是放上了扶苏最喜欢的一首《不老梦》.
与Day1的第二题一样,今天的第二题依然是一道树论题.
我们定义一棵\(n\)个节点的树为一个有\(n\)个节点和\(n-1\)条边的无向连通图.
如果我们定义\(u\)是一颗树\(T\)的根,那么任意一个节点\(v\)到根的路径就是从\(v\)出发到达点\(u\)的简单路径上所经过的点的点集。可以证明这样的简单路径有且仅有一条
定义一个节点\(x\)是节点\(y\)的孩子,当且仅当\(x\)和\(y\)之间有边相连且\(x\)不在\(y\)到根的路径中。如果\(x\)是\(y\)的孩子,那么定义\(y\)是\(x\)的家长节点.
如果我是_rqy那种毒瘤神仙的话,可能会问你每个节点的孩子数不超过\(k\)的\(n\)个节点的带标号无根树一共有多少个,可惜这个问题我也不会,所以我不会问你这么毒瘤的问题.
扶苏从一颗\(n\)个节点的树的1号节点出发,沿着树上的边行走。当然我们约定1号节点是这棵树的根。他所行走的规定是:当扶苏在点 \(u\)时,扶苏要么在\(u\)的孩子中选择一个没有到达过得点\(v\)并行走到\(v\),要么选择回到\(u\)的家长节点.
现在给每个节点一个权值\(w\),其中i 号节点的权值为\(w_i\)。扶苏有一些石子,他想给这棵树上的某一个节点放上石子。我们规定扶苏能在节点\(u\)放上石子当且仅当满足如下条件:
1、扶苏当前在节点\(u\)
2、对于\(u\)的所有孩子节点\(v\),节点\(v\)被放上了\(w_v\) 颗石子。
但是,扶苏在任意时刻都可以取回任意节点的石子。
现在,扶苏想问问你对于每个节点,如果他想在i 号节点上放\(w_i\)颗石子,那么他一开始需要准备多少石子.
有人说T3比T2简单,然而我在考场上对于T2更有思路...
今天大佬在讲题时跟我的思路大致一致(woc大致一致!!!!)
分析思路:
由题可知,要拿到整体最优需要考虑前面的石子如何才能充分利用
我们知道前面节点的石子能够利用的条件是当前处理子节点的几个儿子节点已满并且孙子节点非空,再且就是当其同辈节点已经填上石子的情况下,将其孩子节点进行"剥削",将其石子取走,
现在难免要面对这么一个问题:
在处理某一个节点(就是同辈节点)的最小花费时,如何安排顺序才能致使结果最优呢?
现在考虑一层有\(n\)个节点,其中该层节点本身需要的石子数先不考虑,只考虑其
因为现在我们考虑每个节点处理的顺序的原因是要考虑对其子节点所含石子的利用,
就是要考虑哪个节点的子节点所含石子在填满(满足填该节点本身)并且该节点已经填了石子时,其子节点的石子可以拿出来用,
那么如果当前节点的子节点石子较多,在把此节点的石子填上以后,可重复利用的石子也较多
举个栗子啦....
如图:

现在假如4 5节点需要8个石子,6 7节点需要90个石子,2节点需要2个石子,3节点需要10个石子,
分两种情况讨论:
1.先填2节点(意味着先填满4 5节点)
那么先取8+2个石子填满2,4,5节点,现在可以拿出2号节点的子节点中所有石子(当然2节点不能取)来填3号及其子节点,那么取下面的8个石子,现在右边需要的总共100个石子中填了8个,还需另外92个石子,只能再次造成花费,添加石子,此时显然造成了极大浪费,需要使用108个石子.
2.先填3节点
先取100个石子填3号及其子节点,辣么那么现在的花费是100,再同样将3号的子节点石子取出利用,填2号等,此时我们发现这90个剩余石子不仅能够完成填满2号及其子节点的任务,还能去填1号节点或是2,3号的兄弟节点,(仅在这棵确定的二叉树下)对于填满2,3所在层,仅需石子100枚(怎么量词突然正经?)
通过以上案例模拟易知,也可推知,在处理某层节点时,需要先处理子节点所含石子多的,
(当时考虑暴搜来着,实际就是暴搜,然而并不会处理变量关系...)
再同样的复读一遍给出公式推导与证明:
设本层有两个节点\(i\)与\(j\),设其子节点所含石子总数为\(a_i\)与\(a_j\),
其本身的花费为\(w_i\)与\(w_j\),现在令\(a_i>a_j\)
则有:
先买\(i\)的花费是\(max(w_i+a_i,w_i+w_j+a_j)\)
同理先买\(j\)的花费是\(max(w_j+a_j,w_j+w_i+a_i)\)
化简得这样两个式子:
\(w_i+max(a_i,w_j+a_j)\)
\(w_j+max(a_j,w_i+a_i)\)
展开式子:
1式有两种情况:
\(w_i+a_i\)或\(w_i+w_j+a_j\)
然而第二个铁定只有一种:
\(w_j+a_i+w_i\), 因为\(a_i\)始终大于\(a_j\)
作差一减便知,无论如何二式减一式总大于等于零,
所以无论如何选\(a_{较大的那个}\)总是最优方案,扩展一下会发现这是无论树高的统一结论,
现在剩下所要做的就是搜索!!
现在需要注意几点:
1.考虑的处理顺序序列其实是不上升序列而非递减序列,因为可以有相等的情况出现...
2.在进行深搜时,如果一个个跑一边就显得太蠢了,不如在每次递归处理子节点时将节点按此规则排序,这也是一种优化的方案, 不然会丢30分(一个点30分)
没亲测,但有效~
代码贴上(又是好神奇的二空格首行缩进,这就是强者的世界嘛?):
#include <cstdio>
#include <vector>
#include <algorithm>
const int maxn = 100010;
int n;
int MU[maxn], ans[maxn];
std::vector<int>son[maxn];
void dfs(const int u);
bool cmp(const int &_a, const int &_b);
int main() {
freopen("yin.in", "r", stdin);
freopen("yin.out", "w", stdout);
scanf("%d", &n);
for (int i = 2, x; i <= n; ++i) {
scanf("%d", &x);
son[x].push_back(i);
}
for (int i = 1; i <= n; ++i) {
scanf("%d", MU + i);
}
dfs(1);
for (int i = 1; i < n; ++i) {
printf("%d ", ans[i]);
}
printf("%d\n", ans[n]);
return 0;
}
void dfs(const int u) {
for (auto v : son[u]) {
dfs(v);
}
std::sort(son[u].begin(), son[u].end(), cmp);
int _ret = 0;
for (auto v : son[u]) {
if (_ret >= ans[v]) {
_ret -= ans[v];
} else {
ans[u] += ans[v] - _ret;
_ret = ans[v] - MU[v];
}
}
ans[u] += std::max(0, MU[u] - _ret);
}
inline bool cmp(const int &_a, const int &_b) {
return (ans[_a] - MU[_a]) > (ans[_b] - MU[_b]);
}
考试总结T2(接上次整的T1)的更多相关文章
- 三个线程T1,T2,T3.保证顺序执行的三种方法
经常看见面试题:有三个线程T1,T2,T3,有什么方法可以确保它们按顺序执行.今天手写测试了一下,下面贴出目前想到的3种实现方式 说明:这里在线程中我都用到了sleep方法,目的是更容易发现问题.之前 ...
- C# Tuple<T1,T2....T>元组的使用
1) 先说组元:一个数据结构,由通过逗号分割的,用于传递给一个程序或者操作系统的一系列值的组合. NET Framework 直接支持一至七元素的元组 Tuple<T1> Tuple< ...
- Tuple<T1,T2,.........T> 元组简单使用
元组:一个数据结构,逗号分隔,用于传递一个程序或者操作系统的一系列值得组合 NET Framework直接支持一至七元素得数组 Tuple<T1> Tuple<T1,T2> T ...
- [程序员代码面试指南]二叉树问题-判断t1树是否包含t2树的全部拓扑结构、[LeetCode]572. 另一个树的子树
题目1 解 先序遍历树1,判断树1以每个节点为根的子树是否包含树2的拓扑结构. 时间复杂度:O(M*N) 注意区分判断总体包含关系.和判断子树是否包含树2的函数. 代码 public class Ma ...
- [考试反思]1026csp-s模拟测试88:发展
不用你们说,我自己来:我颓闪存我没脸. 昨天的想法, 今天的回答. 生存, 发展. 总分榜应该稍有回升,但是和上面的差距肯定还是很大. 继续. 为昨天的谬误,承担代价. T2和T3都值得张记性. T2 ...
- NOI2015考试小结
这次NOI2015有幸获得金牌考进了国家集训队,意味着我的OI退役时间既省选之后有延迟了好几个月,又有了新的目标吧. 先说一下考试之外的感受吧,学军宿舍很牛X,接待NOIers而不提供插座,唯一可以用 ...
- 2019.3.18考试&2019.3.19考试&2019.3.21考试
2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...
- [考试反思]0919csp-s模拟测试47:苦难
ISOLATION 也不粘上面的了,先管好自己. 附了个近期总分,可以看出什么. 反思一下考试心态: 开场看题目,T1傻逼题不用脑子,T2傻逼板子,T3... 这T3是啥啊?没看懂题目啊?再看一遍.啥 ...
- [考试反思]0809NOIP模拟测试15:解剖
说在前面: 不建议阅读.这里没有考试经验,只有一大堆负面情绪. 看了你不会有什么收获.看完了就不要怪我影响了你的心情. 以后不粘排行榜了.没什么意思没什么用. 但是我的意思并不是因为这次没考好的一时兴 ...
随机推荐
- Python程序中的进程操作-进程间数据共享(multiprocess.Manager)
目录 一.进程之间的数据共享 1.1 Manager模块介绍 1.2 Manager例子 一.进程之间的数据共享 展望未来,基于消息传递的并发编程是大势所趋 即便是使用线程,推荐做法也是将程序设计为大 ...
- 抓包工具之fiddler实战2-设置断点
Fiddler作为抓工具包,功能强大,作为代理服务器,可以对抓获到的请求或响应进行修改,然后模拟客户端发送新的请求或模拟服务器返回修改后的响应结果. Fiddler中设置断点修改Request Fid ...
- IT兄弟连 Java语法教程 流程控制语句 分支结构语句1
不论哪一种编程语言,都会提供两种基本的流程控制结构:分支结构和循环结构.其中分支结构用于实现根据条件来选择性地执行某段代码,循环结构则用于实现根据循环条件重复执行某段代码.Java同样提供了这两种流程 ...
- 用Scriban进行模版解析
前言 有些时候,我们需要根据模版去展示一些内容,通常会借助模版引擎来处理. 举个简单的例子,发短信. 短信肯定是有模版的,不同的场景对应不同的模版. 注册的, [xxx]恭喜您成功注册yyy平台,您的 ...
- 【BZOJ1921】【CTSC2010】珠宝商(点分治,后缀自动机)
[BZOJ1921][CTSC2010]珠宝商(点分治,后缀自动机) 题面 洛谷 BZOJ权限题 题解 如果要我们做暴力,显然可以以某个点为根节点,然后把子树\(dfs\)一遍,建出特征串的\(SAM ...
- 【mysql】Mysql5.7--sys_schema视图
前言: MySQL 5.7中引入了一个新的sys schema,sys是一个MySQL自带的系统库,在安装MySQL 5.7以后的版本,使用mysqld进行初始化时,会自动创建sys库. sys库里面 ...
- Spring Boot 中如何配置 Profile
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- springmvc字符编码过滤器CharacterEncodingFilter浅析
一.在web.xml中的配置 <!-- characterEncodingFilter字符编码过滤器 --> <filter> <filter-name>cha ...
- Android TextView文本处理库推荐
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/115 Android TextView文本处理库推荐 现在 ...
- mysql-操作篇
# ### mysqlctrl + l 清屏ctrl + c 终止[linux]service mysql start 启动mysqlservice mysql stop 停止mysqlservice ...