二叉图(高级数据结构)

一、定义

二叉图(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_front

q.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比例的中间值

这里写图片描述

猜你喜欢

转载自blog.csdn.net/shm20000412/article/details/52860709