c++ 左偏树简析 猴王例题讲解

题目:猴王 Monkey King

题目描述

很久很久以前,在一个广阔的森林里,住着n只好斗的猴子。起初,它们各干各的,互相之间也不了解。但是这并不能避免猴子们之间的争吵,当然,这只存在于两个陌生猴子之间。当两只猴子争论时,它们都会请自己最强壮的朋友来代表自己进行决斗。显然,决斗之后,这两只猴子以及它们的朋友就互相了解了,这些猴子之间将再也不会发生争论了,即使它们曾经发生过冲突。
假设每一只猴子都有一个强壮值,每次决斗后都会减少一半(比如10会变成5,5会变成2.5)。并且我们假设每只猴子都很了解自己。就是说,当它属于所有朋友中最强壮的一个时,它自己会站出来,走向决斗场。

输入

输入分为两部分。
第一部分,第一行有一个整数n(n<=100000),代表猴子总数。
接下来的n行,每行一个数表示每只猴子的强壮值(小于等于32768)。
第二部分,第一行有一个整数m(m<=100000),表示有m次冲突会发生。
接下来的m行,每行包含两个数x和y,代表第x个猴子和第y个猴子之间发生冲突。

输出

输出每次决斗后在它们所有朋友中的最大强壮值。数据保证所有猴子决斗前彼此不认识。

样例输入
  5
  20
  16
  10
  10
  4
  4
  2 3
  3 4
  3 5
  1 5
样例输出
  8
  5
  5
  10

解析

首先,看到题目我们首先会想到,并查集和堆,因为我们每一次都要从一群猴子中找出最强壮的,暴力搜一遍显然不行,因此要用到堆,然后两只猴子打架后需要将两群猴子合并,因此要用到并查集,但是同时写这两种数据结构太麻烦,所以要借助一种既具有查找功能又具有合并功能的数据结构–左偏树。
下面简单讲一讲左偏树,首先定义几个概念,
1.外结点:左子树或右子数为空的结点即无左子树或右子树。
2.结点i的距离:结点i到后代最近的外结点的所经过的边数。
3.左偏性质:一棵左偏树中任意结点的左子结点距离大于右子节点距离。

上图摘自百度百科

图中外结点有18 20 19 24 15 30 28 11 21 16 42 50 33 26 27。
蓝色数字为该结点的距离。
由第二,三条概念得一个结点的距离一定是它右子结点(如果有)的距离+1,因为左子结点距离大于等于右子结点距离,结点距离又要求最近。

左偏树基本操作(大根为例):

1.合并操作(合并两棵左偏树):将两棵树中较大的根结点,作为合并后的树的根结点,将根较小的树与根较大的树的右子结点继续合并操作,直到无子结点。合并后如果不满足左偏树性质,即左子结点距离小于右子结点距离则维护,即交换指针。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值