二叉图(高级数据结构)

来源:互联网 发布:ubuntu sd卡挂载 编辑:程序博客网 时间:2024/06/14 23:37

一、定义

二叉图(Binary-Map),一种C++14规范中引入的高级数据结构。其集合了二叉树和图论的优点,在世界算法数据结构大会上由斯茂·斯迪尤德恩特首先提出。
  二叉图在形式上类似于二叉树,其实现类似于图论(在下面的代码中有介绍)。由N个点,E条边构成,E在等于N-1时二叉图的复杂度退化为二叉树,其主要特征是二叉图的深度为depth以下的点中可以以图的方式两两连接,并忽略其中边权,直接理解为两点重合,从而达到以二叉形式实现连通环的目的。
  其形式近似于完全连通的杨辉三角或子节点重合的完全二叉树,在时间操作上遍历可以达到O(nlog1/n)的极低复杂度。适用于LCA查询任意点,在实现大规模数据时建树复杂度近似级数求和。
  虽然称作二叉,但其实际上是图论适用的内容,广泛适用于各大领域,在优化近似堆维护SPFA等算法上都有应用。
  完全二叉图和满二叉图的原理类似,但极易由于数据退化,因此这里不作探讨。
  在NOIP2013初赛第九题中命题组首次引入了此概念。



二、STL实现

binary_map<pair<int,int> > q;q.push_back(make_pair(u,v))//建边q.push_front(make_pair(u,v))//建边这两个都是建边,但是可能导致遍历的方式不同q.find_root()//return 图的根节点q.size()//return 图的大小q.get_depth()//return 图的深度q.empty()//如果图为空,return false,否则,return true;q.top()//return 是pair<int,int>型的边q.back()//return 是pair<int,int>型的边区别同push_back与push_frontq.pop()//根据前序遍历弹出第一个点q.back_pop()//根据后序遍历弹出第一个点q.begin()//return iterator型的指针,返回第一个数据q.end()//return iterator型的指针,返回最后一个数据q.__lca(int x,int y)//return a与b的最近公共点priority_binarymap<pair<int,int> >q;由于优先二叉图具有的性质类似于优先队列,内部用斐波那契堆维护,不过只能从一头取出元素。q.push(make_pair<u,v>);//将一条边放入堆内q.top();//返回边权值最小的一条边,返回的类型是pair<int,int>q.pop();//弹出堆顶的元素q.empty();//如果图为空,则返回false,否则,返回true同时与优先队列相同,也有小根堆priority_binarymap<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> >


三、二叉图的应用

这里需要先引进一个概念,二叉图的重心。
该重心的概念是和该数据结构同时在大会上提出的,重心的概念类似于信息学中的数据结构的树的重心。
其主要意义出自于其几何概念,实现由C++的标准库进行。
二叉图的重心通过深度优先搜索来遍历,从而实现了该二叉图边权的中心搜索,在最大流和二叉图对称完备匹配中有广泛的应用。

struct node{    int lc,rc;    int value;}binary_map[N];int dis[N][N];void dfs(int root){    int lc,int rc;    if(binary_map[root].lc)    lc+=dfs(binary_map[root].lc)+dis[root][binary_map[root].lc];    else    return 0;    if(binary_map[root].rc)    rc+=dfs(binary_map[root].rc)+dis[root][binary_map[root].rc];    else    return 0;    binary_map[root].value=lc+rc;}遍历binary_map中,求lc与rc比例的中间值

这里写图片描述

1 0