边分治讲解

前言:

  边分治和点分治一样属于树分治的一部分,相比于点分治,边分治对于与度数相关的问题有着很大的优势,同时边分治也是解决树上最优化问题的一种重要的算法。

分治过程:

  边分治的分治过程与点分治类似,同样每次分治时找到一条分治中心边使这条边两端的两个联通块中较大的一个尽量小。以分治中心边为界限,恰好将当前分治的联通块中的点分成了两部分,统计路径经过分治中心边的答案,然后将分治中心边断开,递归分治中心边两端的两个联通块。

代码实现:

找分治中心边

找分治中心边和找树的重心方法类似,同样记录子树大小,对于每条边取这条边的子节点子树大小size及联通块大小-size中较大的一个更新分治中心边。代码中sum为联通块大小。

inline void getroot(int x,int fa,int sum)
{size[x]=1;for(int i=head[x];i;i=next[i]){if(!vis[i>>1]&&to[i]!=fa){getroot(to[i],x,sum);size[x]+=size[to[i]];int mx_size=max(size[to[i]],sum-size[to[i]]);if(mx_size<num){num=mx_size;root=i;}}}
}

边分治

因为我们需要知道分治中心边的两端点,所以在开双向边时边的编号要从2开始,这样x与x^1就是一对双向边。代码中的calc函数是统计经过分治中心边的答案。

inline void partation(int x,int sum)
{num=INF;getroot(x,0,sum);if(num==INF){return ;}int now=root;vis[now>>1]=1;cnt=0;dfs2(x,0,to[now],1);dfs2(to[now],0,0,2);calc();int sz=size[to[now]];partation(to[now],sz);partation(x,sum-sz);
}

多叉树转二叉树

边分治的时间复杂度同样是$O(nlogn)$,但会被菊花图卡成$O(n^2)$,所以我们要将多叉树转成二叉树,这样虽然会有一个二倍常数但可以保证时间复杂度是$O(nlogn)$。

多叉树转二叉树的方法有两种:

1、第一种方法是从1开始枚举每个点,对于一个点$x$,如果他有<=2个子节点,那么直接向子节点连边即可;否则新建两个点,将$x$连向这两个点,并将$x$的子节点按奇偶分类暂时归为这两个新建点的子节点。为了不影响原树深度等信息,我们将连向新建点的边权设为0。这样新建树因为每条原树边会被存$logn$次,所以空间复杂度是$O(nlogn)$,新建节点数$O(n)$。代码中m为总点数。

void rebuild()
{tot=1;for(int i=1;i<=n;i++){head[i]=0;}for(int i=1;i<=n;i++){int len=q[i].size();if(len<=2){for(int j=0;j<len;j++){add(i,q[i][j],(q[i][j]<=m));add(q[i][j],i,(q[i][j]<=m));}}else{int ls=++n;int rs=++n;v[ls]=v[rs]=v[i];add(i,ls,0);add(ls,i,0);add(i,rs,0);add(rs,i,0);for(int j=0;j<len;j++){if(j&1){q[ls].push_back(q[i][j]);}else{q[rs].push_back(q[i][j]);}}}}
}

2、第二种方法是dfs整棵树,对于原树每个点x,记录一个$last$(初始为x),每次将$last$连向一个子节点,并新建一个点$y$将$last$连向$y$,然后将$last$改为$y$。同样将连向新建点的边权设为0。因为每个原树边只被保存一次,所以空间复杂度是$O(n)$,新建点数是$O(n)$。代码中m为总点数。

inline void rebuild(int x,int fa)
{int tmp=0;int last=0;int len=v[x].size();for(int i=0;i<len;i++){int to=v[x][i].first;int val=v[x][i].second;if(to==fa){continue;}tmp++;if(tmp==1){add(x,to,val);add(to,x,val);last=x;}else if(tmp==len-(x!=1)){add(last,to,val);add(to,last,val);}else{m++;add(last,m,0);add(m,last,0);last=m;add(m,to,val);add(to,m,val);}}for(int i=0;i<len;i++){if(v[x][i].first==fa){continue;}rebuild(v[x][i].first,x);}
}

边分治的性质:

1、如果我们在边分治找中心时以当前联通块在原树中深度最小的点为根,那么找到的分治中心边在原树中一定是一条从父节点$u$到子节点$v$的边,这条边将当前联通块分成了两部分,可以发现包含$v$的那部分一定是原树中的一棵子树,我们假设包含$u$的部分为$S$,包含$v$的部分为$T$,那么$S$中的任意一个点$x$与$T$中的任意一个点$y$的$lca$一定不在$T$中,这也就说明$x$与$T$中所有点的$lca$都相同,就是$lca(x,v)$。

2、边分治将每次的分治联通块中的点恰好分成了两部分,这就省去了像点分治那样单独处理以分治重心为路径端点的答案这一过程。

边分树:

与点分树类似,我们将每层分治中心边连向下一层的分治中心边所形成的树就是边分树,边分树是一棵二叉树,它可以类似线段树一样合并,这一部分内容暂时还不完整,待博主后续更新。

练习题:

BZOJ2870最长道路(边分治模板题)

CSTC2018暴力写挂(两棵树,第一棵树边分治转到第二棵树上建虚树DP)

WC2018通道(三棵树,码量较大)

转载于:https://www.cnblogs.com/Khada-Jhin/p/10154994.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pycharm社区版配置Django

Pycharm开发版(收费)自带Django模板&#xff0c;社区版(免费)需要通过命令行创建Django项目。 通过pip安装Django&#xff1a;pip install django2.0.2(版本号)&#xff0c;可通过以下命令检查是否安装成功 在命令行下创建Django项目(项目存放在D:\PyCharm) 1.创建项目 进入D:\…

用Mesos分布式架构进行工作

引言&#xff1a;2010年&#xff0c;一个旨在解决扩容问题的项目诞生——Apache Mesos&#xff0c;它在某种程度上对CPU、内存、磁盘资源进行抽象&#xff0c;从而允许整个数据中心如同单台大服务器般运转。无需虚拟机和操作系统&#xff0c;Mesos创造了一个单独底层的集群为应…

不一样的视角,程序员世界里的环保

摘要&#xff1a; 我们身边有很多可以做的技术环保工作。比如说&#xff0c;在Linux下少用root用户&#xff0c;SQL的时候&#xff0c;delete前先select&#xff0c;这样&#xff0c;你就不会做出一些让你后悔的事。不会让你重头来过&#xff0c;从而至少不会浪费电能。写代码的…

oracle 会话 lock,相克军_Oracle体系_随堂笔记014-锁 latch,lock

1、Oracle锁类型锁的作用latch锁&#xff1a;chain&#xff0c;链LOCK锁排他锁(X)共享锁(S)2、行级锁&#xff1a;DML语句事务锁TX锁的结构事务锁的加锁和解锁过程只有排他锁不影响读(CR块)3、表级锁&#xff1a;TM行级排他锁(Row exclusive)RX锁当我们进行DML时&#xff0c;会…

TIOBE 10月编程语言排行榜 : GO 问鼎本年度语言 ?

距离2016年度编程语言的公布只剩3个月了&#xff0c;谁将夺得桂冠&#xff1f; 与去年同期相比&#xff0c;2016年只有Go语言和Groovy语言的增长率超过了1%。 需要注意的是&#xff0c;Groovy语言2015年以一个爆炸性增长的收尾&#xff0c;所以到2017年1月左右的增长速度可能不…

使用 ReSharper,输入即遵循 StyleCop 的代码格式化规范

StyleCop 可以帮助强制执行代码格式化规范&#xff0c;ReSharper 可以帮助你更高效地编写代码。把两者结合起来&#xff0c;你便能高效地编写符合团队强制格式化规范的代码来。 本文就介绍如何使用 ReSharper 来高效地遵循 StyleCop 的代码格式化规范。 本文内容 安装插件 Styl…

C# 控件双缓冲控制 ControlStyles 枚举详解

ControlStyles 枚举.NET Framework 4指定控件的样式和行为。 此枚举有一个 FlagsAttribute 特性&#xff0c;通过该特性可使其成员值按位组合。 命名空间&#xff1a; System.Windows.Forms程序集&#xff1a; System.Windows.Forms&#xff08;在 System.Windows.Forms.dll …

Java 9 将采用新的版本字符串格式

在现有的版本编码格式使用了两年之后&#xff0c;从Java 9开始&#xff0c;Java版本方案将根据业内软件版本编码的最佳实践进行修改。使用或解析Java版本字符串的应用程序开发人员要注意了&#xff0c;因为这种变化可以会影响他们的应用程序。 正如JEP 223所阐述的那样&#xf…

jQuery(爱前端)

一 jQuery 简介 官网&#xff1a;www.jquery.com 口号&#xff1a;写更少的代码&#xff0c;做更多的事情 jQuery 是一个快速、小型的、特性很多的JS库&#xff0c;它把很多事儿都变得简单。jQuery是免费的、开源的。 jQuery 是 DOM 编程领域的霸主&#xff0c;极大的简化了原生…

CentOS 7 firewalld使用简介

2019独角兽企业重金招聘Python工程师标准>>> Centos升级到7之后&#xff0c;发现无法使用iptables控制Linuxs的端口&#xff0c;google之后发现Centos 7使用firewalld代替了原来的iptables。下面记录如何使用firewalld开放Linux端口&#xff1a; 1.快速使用说明 开启…

一个备份sql server文件.bak还原成两个数据库

一直对这个概念很模糊&#xff0c;今天具体一点。 备份文件只要是正常的.bak文件就好。 数据库>还原数据库 直接填写还原之后的文件名就行。 用一份备份文件还原两个一样的库&#xff0c;只是名称不一样。 转载于:https://www.cnblogs.com/Ly426/p/10209825.html

linux服务器防病毒,Linux系统中你不需要防病毒?_服务器评论-中关村在线

误区4&#xff1a;Linux是无病毒。Linux的安全性这么好&#xff0c;这是否意味着Linux是无病毒吗&#xff1f;现实&#xff1a;Linux是非常安全&#xff0c;并不是没有针对Linux方面的病毒。有许多针对Linux的已知病毒。但是几乎所有的已知病毒对于Linux在本质上都是非破坏性的…

python面向对象-1方法、构造函数

类是指&#xff1a;描述一种事物的定义&#xff0c;是个抽象的概念 实例指&#xff1a;该种事物的一个具体的个体&#xff0c;是具体的东西 打个比方&#xff1a; “人”是一个类。“张三”是人类的一个具体例子 在编程时也是同样的道理&#xff0c;你先自己定义一个“类”&am…

bzoj3503: [Cqoi2014]和谐矩阵

高斯消元解异或方程组。学了bitset。对比如下 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define REP(i,s,t) for(int is;i<t;i) #define dwn(i,s,t) for(int is;i>t;i--) #define clr(…

sys模块

与python解释器交互的模块 sys.argv 命令行参数List&#xff0c;第一个元素是程序本身路径 sys.exit(n) 退出程序&#xff0c;正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径…

Oracle中SQL语句学习五(统计分组语句group by和having)

oracle&#xff08;41&#xff09; 在 应用系统开发中&#xff0c;进行需要统计数据库中的数据&#xff0c;当执行数据统计时&#xff0c;需要将表中的数据进行分组显示&#xff0c;在统计分组中是通过group by子句、分组函数、having子句共同实现的。其中group by子句用于指定…

做开发十年,我总结出了这些开发经验

本文由云社区发表,原文转载地址:https://www.cnblogs.com/qcloud1001/p/10218876.html 在一线做了十年的开发&#xff0c;经历了网易、百度、腾讯研究院、MIG 等几个地方&#xff0c;陆续做过 3D 游戏、2D 页游、浏览器、移动端翻译 app 等。 积累了一些感悟。必然有依然幼稚的…

2016年4月 TIOBE 编程语言排行榜

4月头条: Visual Basic 正在渐行渐远 COBOL, BASIC 和 FORTRAN 很长一段时间作为主力开发语言被使用。有很多软件使用这些语言来编写&#xff0c;并且发展的不亦乐乎。然而经过多年的发展&#xff0c;COBOL和FORTRAN逐渐被抛弃&#xff0c;而得益于微软的存在&#xff0c;BASIC…

基于zbus的MySQL透明代理(100行)

项目地址 https://git.oschina.net/rushmore/zbus 我们上次讲到zbus网络通讯的核心API&#xff1a; Dispatcher -- 负责-NIO网络事件Selector引擎的管理&#xff0c;对Selector引擎负载均衡 IoAdaptor -- 网络事件的处理&#xff0c;服务器与客户端共用&#xff0c;负责读写&am…

linux path环境变量起什么作用,shell基础(5)PATH环境变量的作用和使用方法

释放双眼&#xff0c;带上耳机&#xff0c;听听看~&#xff01;关于PATH的作用PATH说简单点就是一个字符串变量&#xff0c;当输入命令的时候LINUX会去查找PATH里面记录的路径。比如在根目录/下可以输入命令ls,在/usr目录下也可以输入ls,但其实ls这个命令根本不在这个两个目录下…