「转载」基环树学习笔记

news/2025/2/23 22:51:11
markdown">

markdown源码-原地址">本文转载于cly_none,并在此基础上修改 已征得本人同意并获取markdown源码 原地址


基环树,也是环套树,简单地讲就是树上在加一条边。它形如一个环,环上每个点都有一棵子树的形式。因此,对基环树的处理大部分就是对树处理和对环处理。显然,难度在于后者。

BZOJ1791 Island

题意:有一个基环树和树组成的森林,共有\(n\)个结点,边有边权。试求其中所有联通块的直径之和。

\(n \leq 10^6\)

我们只用考虑如何求出一个基环树的直径。

首先,我们要对环上所有点的子树求出它们的直径和最大深度。然后,我们只用考虑在环上至少经过一条边的路径。那么,这种路径在环上一定有起始点和终点。(假设路径是从起始点开始,按顺时针方向走达到终点)

不妨枚举这段路径在环上的终点。由于规定了这个点和方向,我们就可以拆环了。然后是一个经典的技巧,把环上元素复制一遍,就可以枚举全部拆环方案。设环上有\(l\)个结点。那么,我们枚举终点,就相当于在长度为\(2l\)的数组上不断滑动一个长度为\(l\)的区间。

剩下的问题与基环树已经没什么关系了。设环上边权的前缀和为\(sum\),环上结点的子树的最大深度为\(dep\)
那么,在环上起始点为\(i\),终点为\(j\)的路径能得到的长度就是\(sum_j - sum_i + dep_j + dep_i\)。既然枚举了\(j\),我们在滑动区间时就只用维护\(dep_i - sum_i\)的最大值就可以了。这个可以用单调队列实现。

时间复杂度\(O(n)\)


CF835F. Roads in the Kingdom

题意:有一棵\(n\)个结点的基环树,边有边权。需要从环上删去一条边,以最小化直径。输出最小化后的直径。

\(n \leq 2 \times 10^5\)

本题和上道题类似,做法也相近。我们只用枚举删掉的是哪一条边,然后因为路径长度是\(sum_j+dep_j-sum_i+dep_i\)
我们用两个set维护所有\(sum_i+dep_i\)\(-sum_i + dep_i\)。这样就能求直径只要从两个set中分别取出最大值就好了。当然,还要特判两个最大值是同一个结点的情况。

时间复杂度\(O(n \log n)\)


BZOJ2878 迷失游乐园

题意:有一棵\(n\)个结点的基环树,边有边权。当你从一个结点出发后,你每次会等概率地选择下一个未被访问过的结点,并走到那个结点,直到与当前点相邻的结点都被访问过为止。试求等概率选择出发点,所走的路径长度的期望值。

\(n \leq 10^5\)

先考虑如何对树做这个问题。我们设\(dp_i\)为从结点\(i\)开始,只向孩子结点走的路径的期望长度。按照题意可以得到\(dp_i = \frac {\sum_{j \in ch_i} dis(i,j) + dp_j} {|ch_I|}\)。在计算出所有\(dp\)值后,再从父亲向孩子结点更新,得到每个点的答案。这样,就是两遍树形dp,一次从下往上更新,一次从上往下更新。

然后考虑对环的处理。环上的两个结点互相到达,既可以按顺时针方向走,也可以按逆时针方向走。因此,我们枚举这个方向,就可以拆环了。
然后,我们可以用类似的方法,求出环上结点之间的贡献。这里特别提及一个细节,当在环上向右移动区间时,我们不但要删去区间旧左端点的贡献,还要考虑新左端点因为成为边界,不能再向左走,其贡献会增加。
更确切地说,设旧左端点为\(u\),新左端点为\(v\),那么,原来对于\(v\)的,有\(\frac {1} {|ch_v| + 1}\)的可能向\(u\)走,但现在,就只有向它的子树走的可能了,故\(v\)的贡献会改变。

这样,通过一次dfs,两次环上处理,再加一遍dfs,就能解决本题。

时间复杂度\(O(n)\)


上面的问题中,我们可以直接拆环,把环上元素复制一遍来解决。然而,对于另一些问题,我们需要使用枚举环端点元素的状态的技巧,以实现破环成链。


BZOJ1040 骑士

题意:有一个基环树森林,含有\(n\)个结点。求其带权最大独立集。

\(n \leq 10^6\)

关于如何求树的带权最大独立集,这里便不必赘述了。

考虑处理环,我们枚举其中某个元素选还是不选,就能破环成链了。

时间复杂度\(O(n)\)


ARC079F - Namori Grundy

题意:有一个弱联通的有向图,含有\(n\)个结点和\(n\)条边。试问是否存在方案,赋给每个结点一个自然数权值\(val_i\),满足对于所有结点\(u\)\(val_u = {\rm mex}\{val_v | (u,v) \in E\}\)。一个集合的\(\rm mex\)是没有在这个集合中出现的最小自然数。

\(n \leq 2 \times 10^5\)

唯一能导致无解情况出现的就只有环了。我们扣环之后,对环上所有结点的外向树做dfs,这样就只用考虑环了。

顺便一提,对于所有已知\(\{val_v | (u,v) \in E\}\)的结点\(u\)\(val_u\)直接暴力求就可以了。设\(a_i\)表示\(val_u = i\)时,以\(u\)为根的外向树中最少需要的结点数(包括\(u\))。那么,可以得到:

  • \(a_0 = 1\)
  • \(a_i = \sum_{k=0}^{i-1} a_i + 1\)

对这个数列求通项,得到\(a_i = 2^i\)。因此暴力求\(\rm mex\)\(O(\log n)\)的。

\(S_u\)表示\(\{val_v | (u,v) \in E\}\),那么,对于环上所有结点\(u\)\(val_u\)要么是\({\rm mex} S_u\),要么是\(S_u\)中没有出现的次小的自然数。后一种情况会出现当且仅当\(u\)在环上前一个结点的权值恰好等于\({\rm mex}S_u\)。于是,我们枚举环上某一个结点是上面哪一种情况,在环上扫一遍判断一下就好了。

时间复杂度\(O(n \log n)\)

转载于:https://www.cnblogs.com/mangoyang/p/9314823.html


http://www.niftyadmin.cn/n/976004.html

相关文章

JavaScript 开发的技巧

JavaScript 开发的45个经典技巧 分类 编程技术 JavaScript是一个绝冠全球的编程语言,可用于Web开发、移动应用开发(PhoneGap、Appcelerator)、服务器端开发(Node.js和Wakanda)等等。JavaScript还是很多新手踏入编程世界…

Angular系列学习三:父子组件之间的交互(常见的组件通讯场景)

作者:心叶时间:2018-07-24 16:48:56 通过输入型绑定把数据从父组件传到子组件 通过Input()可以实现父组件传递数据给子组件,下面先看看子组件代码: import { Component, Input } from angular/core;Component({selector: child-co…

map按照value排序的方法

1.将map以pair(string,double)的存储方式加入vector中 2.vector的sort()中的第三个参数重载 #typedef pair<string,double> PAIR struct CmpByValue { bool operator()(const PAIR& lhs, const PAIR& rhs) { return lhs.second < rhs.second; } }; map<QS…

python基础学习笔记(六)

学到这里已经很不耐烦了&#xff0c;前面的数据结构什么的看起来都挺好&#xff0c;但还是没法用它们做什么实际的事。 基本语句的更多用法 使用逗号输出 >>> print age:,25 age: 25 如果想要同时输出文本和变量值&#xff0c;却又不希望使用字符串格式化的话&#xf…

Apache多处理模块

介绍 Apache HTTP 服务器被设计为一个功能强大&#xff0c;并且灵活的 web 服务器&#xff0c; 可以在很多平台与环境中工作。不同平台和不同的环境往往需要不同 的特性&#xff0c;或可能以不同的方式实现相同的特性最有效率。Apache httpd 通过模块化的设计来适应各种环境。这…

某班学生不超过40人,输入某门课程的成绩,具体人数由用户通过键盘输入,用函数编程统计不及格的人数。

#include<stdio.h> #define N 40 int flunk (int n,int people[N]) {int i,counter;for(i0,counter0;i<n;i) { if(people[i]<60) counter; } printf("不及格人数为:%d\n",counter); }int main() {int n;int people[N];printf("请输入…

scala函数返回值

1、使用returndef functionName ([参数列表]) : [return type] { function body return [expr] }2、直接把返回值写在最后&#xff1a; object Test { def main(args: Array[String]) { println( "Returned Value : " addInt(5,7) ); } def addInt( a:Int, b:Int )…

laravel5.4 发送SMTP邮件

https://blog.csdn.net/qq_35843527/article/details/77880631 Lumen / Laravel 5.4 使用网易邮箱 SMTP 发送邮件 获取网易邮箱的服务器和授权码: 登录网易邮箱 (http://mail.163.com/), 获取服务器地址&#xff1a; 点击【设置】 > 【POP3/SMTP/IMAP】:服务器地址: POP3服务…