原题链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1389

大致题意:N只相互不认识的猴子(每只猴子有一个战斗力值)

两只不认识的猴子之间发生冲突,两只猴子会分别请出它们认识的最强壮的

猴子进行决斗。决斗之后这,两群猴子都相互认识了。

决斗的那两只猴子战斗力减半。。。有m组询问

输入a b表示猴子a和b发生了冲突,若a,b属于同一个集合输出-1

否则输出决斗之后这群猴子(已合并)中最强的战斗力值。。。

具体思路:用并查集判断是否属于同一集合,用左偏树维护一群猴子的战斗力值。

加了垃圾回收,否则容易爆内存。。。

具体如下:

 #include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
const int Max_N = ;
struct UnionFind{
int par[Max_N], rank[Max_N];
inline void init(int n){
for (int i = ; i <= n; i++){
par[i] = i;
rank[i] = ;
}
}
inline int find(int x){
while (x != par[x]){
x = par[x] = par[par[x]];
}
return x;
}
inline void unite(int x, int y){
x = find(x), y = find(y);
if (x == y) return;
if (rank[x] < rank[y]){
par[x] = y;
} else {
par[y] = x;
if (rank[x] == rank[y]) rank[x]++;
}
}
};
struct Node{
int v, npl;
Node *ch[];
inline void set(int _v = , int _npl = -, Node *p = NULL){
v = _v, npl = _npl;
ch[] = ch[] = p;
}
inline void push_up(){
npl = ch[]->npl + ;
}
};
struct LeftistTree{
int N, top;
UnionFind rec;
Node *tail, *null;
Node stack[Max_N], *ptr[Max_N], *store[Max_N];
void init(int n){
tail = &stack[];
null = tail++;
null->set();
N = n, top = , rec.init(n);
}
inline Node *newNode(int v){
Node *p = null;
if (!top) p = tail++;
else p = store[--top];
p->set(v, , null);
return p;
}
inline Node* Merge(Node* &x, Node* &y){
if (x == null) return y;
if (y == null) return x;
if (y->v > x->v) std::swap(x, y);
x->ch[] = Merge(x->ch[], y);
if (x->ch[]->npl > x->ch[]->npl)
std::swap(x->ch[], x->ch[]);
x->push_up();
return x;
}
inline int get_max(int i){
return ptr[i]->v;
}
inline void insert(){
int v;
for (int i = ; i <= N; i++){
scanf("%d", &v);
ptr[i] = newNode(v);
}
}
inline void del(int i){
int ret = get_max(i);
Node *x = newNode(ret >> );
store[top++] = ptr[i];
ptr[i] = Merge(ptr[i]->ch[], ptr[i]->ch[]);
ptr[i] = Merge(ptr[i], x);
}
inline void gogo(int a, int b){
int ans = ;
a = rec.find(a), b = rec.find(b);
if (a == b){
printf("-1\n");
return;
}
rec.unite(a, b);
del(a), del(b);
if (rec.rank[a] > rec.rank[b]){
ptr[a] = Merge(ptr[a], ptr[b]);
ans = ptr[a]->v;
} else {
ptr[b] = Merge(ptr[a], ptr[b]);
ans = ptr[b]->v;
}
printf("%d\n", ans);
}
}lft;
int main(){
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif
int n, m, a, b;
while (~scanf("%d", &n)){
lft.init(n), lft.insert();
scanf("%d", &m);
while (m--){
scanf("%d %d", &a, &b);
lft.gogo(a, b);
}
}
return ;
}

zoj 2334 Monkey King/左偏树+并查集的更多相关文章

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

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

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

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

  3. 洛谷 - P1552 - 派遣 - 左偏树 - 并查集

    首先把这个树建出来,然后每一次操作,只能选中一棵子树.对于树根,他的领导力水平是确定的,然后他更新答案的情况就是把他子树内薪水最少的若干个弄出来. 问题在于怎么知道一棵子树内薪水最少的若干个分别是谁. ...

  4. 洛谷 - P3377 - 【模板】左偏树(可并堆) - 左偏树 - 并查集

    https://www.luogu.org/problemnew/show/P3377 左偏树+并查集 左偏树维护两个可合并的堆,并查集维护两个堆元素合并后可以找到正确的树根. 关键点在于删除一个堆的 ...

  5. hdu 1512 Monkey King 左偏树

    题目链接:HDU - 1512 Once in a forest, there lived N aggressive monkeys. At the beginning, they each does ...

  6. ZOJ2334 Monkey King 左偏树

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

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

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1512 [题目大意] 现在有 一群互不认识的猴子,每个猴子有一个能力值,每次选择两个猴子,挑出他们所 ...

  8. HDU1512 ZOJ2334 Monkey King 左偏树

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

  9. hdu 1512 Monkey King —— 左偏树

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

随机推荐

  1. 酒鬼-DP

    Description Santo刚刚与房东打赌赢得了一间在New Clondike 的大客厅.今天,他来到这个大客厅欣赏他的奖品.房东摆出了一行瓶子在酒吧上.瓶子里都装有不同体积的酒.令Santo高 ...

  2. CODEVS 1001 舒适的路线

    思路:先按照速度大小对边排序,再枚举最终路径中的速度最大值,并查集,更新答案 #include<iostream> #include<vector> #include<a ...

  3. Android基础总结(4)——广播接收器

    在Android中的每个应用程序可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能来自于系统的,也可能来自于其他应用程序的.Android提供了一整套完整的API, ...

  4. ionic ngcordova camera

    拍照是經常用到的,所以記錄一下 拍照的代碼... 1. ionic start camera blankcd camera ionic platform add ios 2. 添加插件,這裏很熟悉.. ...

  5. Json.net实现方便的Json转C#(dynamic动态类型)对象

    以前需要将一段json字符串转换为C#对象时,一般都是定义一个与之对应的实体类来接收.这样做有一个很大的缺点,就是当字符串特别长,属性特别多,又有嵌套时,手敲这个实体类就非常痛苦. 比如之前做的一个接 ...

  6. css定义表格样式

    table.gridtable { font-family: verdana,arial,sans-serif; font-size:11px; color:#333333; border-width ...

  7. CSS3文字描边 CSS3字体外部描边

    给需要实现文字描边的元素添加如下CSS3的属性 text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0; -webkit-t ...

  8. 将Windows 7导航窗格中的收藏夹、库、家庭组、网络全部去掉

    将Windows 7导航窗格中的收藏夹.库.家庭组.网络全部去掉,只剩下计算机.右键单击ShellFolder,选择权限->Administrators,勾选上“完全控制”,确定后双击右侧窗格中 ...

  9. 《你是我的小羊驼》游戏ios源码

    <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op>源码下载:http://code. ...

  10. 蘑菇街iOS客户端应用源码

    蘑菇街iOS客户端应用源码 随着蘑菇街由导购向电商转型,蘑菇街自己的IM也应运而生,IM起初只是用于商家和买家之间沟通的工具.后面我们问自己,既然已经有了用于客服的IM,为什么不自己做一个IM,用于公 ...