题目链接:HDU - 1512

Once in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its own way and none of them knows each other. But monkeys can't avoid quarrelling, and it only happens between two monkeys who does not know each other. And when it happens, both the two monkeys will invite the strongest friend of them, and duel. Of course, after the duel, the two monkeys and all of there friends knows each other, and the quarrel above will no longer happens between these monkeys even if they have ever conflicted.
Assume that every money has a strongness value, which will be reduced to only half of the original after a duel(that is, 10 will be reduced to 5 and 5 will be reduced to 2).
And we also assume that every monkey knows himself. That is, when he is the strongest one in all of his friends, he himself will go to duel.
Input
There are several test cases, and each case consists of two parts.
First part: The first line contains an integer N(N<=100,000), which indicates the number of monkeys. And then N lines follows. There is one number on each line, indicating the strongness value of ith monkey(<=32768).
Second part: The first line contains an integer M(M<=100,000), which indicates there are M conflicts happened. And then M lines follows, each line of which contains two integers x and y, indicating that there is a conflict between the Xth monkey and Yth.
Output
For each of the conflict, output -1 if the two monkeys know each other, otherwise output the strongness value of the strongest monkey in all friends of them after the duel.
 
题意描述:有n只猴子,每只猴子有一个值,两只猴子如果打架的话,他们的值各自掉一半。给出m个事件,每个事件给出两只猴子,如果两只猴子不认识的话,打完架就成为了朋友(两只猴子的各自朋友也都互相成为了朋友),求出打完架后两只猴子的所有朋友中值最大的。
算法分析:这道题我刚开始做的时候,想到了并查集,以为这就够了(其实时间复杂度我也不敢直视),交上去果断TLE了,后来看了讨论里有说,尼玛,这就是传说中的左偏树的题目啊,果断得好好学习一下,弥补一下自己的数据结构的知识。
说明:头一次搞左偏树,代码是借鉴别人的,不过真心写的比较好就拿来了。同时,推荐一下集训队的论文,基本上看了论文后就对左偏树有了一定的了解了。

左偏树的特点及其应用

 /*左偏树*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x7fffffff
using namespace std;
const int maxn = +; int father[maxn];
struct node
{
int l,r;
int dis;
int strong;
}LTree[maxn];
int Find(int x)
{
if (father[x]==x) return x;
return father[x]=Find(father[x]);
}
int Merge(int x,int y)
{ //返回合并后的根
if (x==) return y;
if (y==) return x;
if (LTree[x].strong < LTree[y].strong) //大顶堆
swap(x,y);
LTree[x].r = Merge(LTree[x].r,y); //递归合并右子树和Y
int l = LTree[x].l , r = LTree[x].r;
father[r] = x; //更新T右子树的根
if (LTree[l].dis < LTree[r].dis) //维护堆性质
swap(LTree[x].l,LTree[x].r);
if (LTree[x].r == ) //如果没有右子树 则距离为0
LTree[x].dis = ;
else
LTree[x].dis = LTree[LTree[x].r].dis + ;
return x;
}
int del(int x)
{ //返回删除根以后左右子树的合并的根
int l,r;
l=LTree[x].l;
r=LTree[x].r;
father[l]=l;
father[r]=r;
LTree[x].l=LTree[x].r=LTree[x].dis=;
return Merge(l,r);
}
void solve(int x,int y)
{
LTree[x].strong /= ;
LTree[y].strong /= ;
//问每次PK以后,当前这个群体里力量最大的猴子的力量是多少。
int left,right;
left = del(x);
right = del(y);
left = Merge(left,x);
right = Merge(right,y);
left = Merge(left,right);
printf("%d\n",LTree[left].strong);
}
int main()
{
int n,m,x,y;
while (scanf("%d",&n)!=EOF)
{
for (int i= ;i<=n ;i++)
{
scanf("%d",&LTree[i].strong);
LTree[i].l=;
LTree[i].r=;
LTree[i].dis=;
father[i]=i; //起始已自己为父亲
}
scanf("%d",&m);
for (int i= ;i<=m ;i++)
{
scanf("%d%d",&x,&y);
int fx=Find(x),fy=Find(y);
if (fx == fy) printf("-1\n");
else solve(fx,fy);
}
}
return ;
}

hdu 1512 Monkey King 左偏树的更多相关文章

  1. hdu 1512 Monkey King —— 左偏树

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 很简单的左偏树: 但突然对 rt 的关系感到混乱,改了半天才弄对: 注意是多组数据! #includ ...

  2. HDU 1512 Monkey King (左偏树+并查集)

    题意:在一个森林里住着N(N<=10000)只猴子.在一开始,他们是互不认识的.但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识 (认识具有传递性)的两只猴子之间.争斗时,两只猴子都 ...

  3. HDU 1512 Monkey King ——左偏树

    [题目分析] 也是堆+并查集. 比起BZOJ 1455 来说,只是合并的方式麻烦了一点. WA了一天才看到是多组数据. 盲人OI (- ̄▽ ̄)- Best OI. 代码自带大常数,比启发式合并都慢 [ ...

  4. HDU 1512 Monkey King(左偏堆)

    爱争吵的猴子 ★★☆ 输入文件:monkeyk.in 输出文件:monkeyk.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 在一个森林里,住着N只好斗的猴子.开始,他们各 ...

  5. ZOJ2334 Monkey King 左偏树

    ZOJ2334 用左偏树实现优先队列最大的好处就是两个队列合并可以在Logn时间内完成 用来维护优先队列森林非常好用. 左偏树代码的核心也是两棵树的合并! 代码有些细节需要注意. #include&l ...

  6. zoj 2334 Monkey King/左偏树+并查集

    原题链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1389 大致题意:N只相互不认识的猴子(每只猴子有一个战斗力值) 两只 ...

  7. HDU1512 ZOJ2334 Monkey King 左偏树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - ZOJ2334 题目传送门 - HDU1512 题意概括 在一个森林里住着N(N<=10000)只猴子. ...

  8. hdu1512 Monkey King(左偏树 + 并查集)

    Once in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its o ...

  9. LuoguP1456 Monkey King (左偏树)

    struct LeftTree{ int l,r,val,dis; }t[N]; int fa[N]; inline int Find(int x){ return x == fa[x] ? x : ...

随机推荐

  1. .NET Core Linux 部署实践

    部署环境:CentOS 7 x64 必要条件:当前用户有sudo权限 1. 安装依赖包sudo yum install libunwind libicu2. 下载.net core安装文件curl - ...

  2. HDU 4346 The Beautiful Road ( 反向考虑 思路题 )

    考虑对立情况,不漂亮的串的形式必然为GGGGR……R……RGGGG 相邻R之间的距离为奇数且相等. #include <cstdio> #include <cstring> # ...

  3. GCC特性之__init修饰解析 - kasalyn的专栏 - 博客频道 - CSDN.NET

    , GCC特性之__init修饰解析 - kasalyn的专栏 - 博客频道 - CSDN.NET.MathJax_Hover_Frame {border-radius: .25em; -webkit ...

  4. iOS 实现设备应用之间的相互切换

    今天突发奇想,想做个应用之间能够切换的demo. 前提条件是,你得知道对应应用程序的URL Scheme.URL Scheme不一定和bundle id相同,但是,一定要是一致的. [[UIAppli ...

  5. Oracle 数据库导出时 EXP-00008;ORA-00904

    问题是客户端和服务器端版本问题,我本地是11g,而服务器端是10g. 规则1:低版本的exp/imp可以连接到高版本(或同版本)的数据库服务器,但高版本的exp/imp不能连接到低版本的数据库服务器. ...

  6. Spring2集成iBatis2

    从数据库中查询一条记录,演示Spring与iBatis的集成 1 编写sqlmaps与Domain对象 <?xml version="1.0" encoding=" ...

  7. easyui中的依赖关系

    参考自:http://www.easyui.info/archives/765.html 在使用easyui的过程中发现各个组件直接存在依赖关系,也就是上层的复杂组件依赖于一个或者多个简单组件,复杂组 ...

  8. hdu1007 平面最近点对(暴力+双线程优化)

    突发奇想,用双线程似乎可以优化一些暴力 比如说平面最近点对这个题目,把点复制成2份 一份按照x排序,一份按照y排序 然后双线程暴力处理,一份处理x,一份处理y 如果数据利用x递减来卡,那么由于双线程, ...

  9. SecureCRT指南

    本文主要介绍SecureCRT的使用方法和技巧. [概念解释]什么是SSH? SSH的英文全称是Secure Shell 传统的网络服务程序,如:FTP和telnet在本质上都是不安全的, 因为它们在 ...

  10. 修改Eclipse发布路劲(Deploy path)

    Eclipse默认的发布路劲在用户的workspace里,比较难找,为了方便查看,可以将发布路劲修改为自己想要的. 修改方法: 1.先stop Servers下tomcat里的项目,然后remove ...