COGS 526 又是一道模板题——左偏树
2015-08-18 17:00
381 查看
这不刚刚学会写左偏树嘛,COGS上正好有个左偏树的分类,本来想做第一道,USACO Jan09的安全路径,可是那道题谜一样的题目描述吓到我了,于是就看了下面那一道,就是这道题。相当于又粘了一下模板。
只需要在结构体中加上一个fa,方便给出节点找出树根,再用并查集判断两只猴子是否在一个堆中(就是已经是朋友的都在一个大根堆中,最开始有n个大根堆)就可以。我没仔细想是否可以直接用并查集的树根表示堆的树根,或者只需要用并查集来做(偷个懒嘿嘿)。
每次给出要争吵的猴子a和b,用并查集判断如果他们是朋友输出-1,如果不是,找出a,b在的堆的根A,B,分别合并A,B的左右孩子,再合并一下。之后把A,B的数据更改一下:权值除以2,左右孩子设为0,再插入到堆中即可。最后输出堆顶。
只需要在结构体中加上一个fa,方便给出节点找出树根,再用并查集判断两只猴子是否在一个堆中(就是已经是朋友的都在一个大根堆中,最开始有n个大根堆)就可以。我没仔细想是否可以直接用并查集的树根表示堆的树根,或者只需要用并查集来做(偷个懒嘿嘿)。
每次给出要争吵的猴子a和b,用并查集判断如果他们是朋友输出-1,如果不是,找出a,b在的堆的根A,B,分别合并A,B的左右孩子,再合并一下。之后把A,B的数据更改一下:权值除以2,左右孩子设为0,再插入到堆中即可。最后输出堆顶。
#include <cstdio> #include <algorithm> #include <cstring> #include <vector> using namespace std; int n, m, f[100005]; struct node{ int w, lc, rc, h, fa; }t[100005]; int find(int x) {return f[x] == x ? x : f[x] = find(f[x]);} int merge(int A, int B){ if(!A) return B; if(!B) return A; if(t[A].w < t[B].w) swap(A, B); t[A].rc = merge(t[A].rc, B); if(t[t[A].lc].h < t[t[A].rc].h) swap(t[A].lc, t[A].rc); if(t[A].rc) t[A].h = t[A].rc+1; else t[A].h = 0; if(t[A].lc) t[t[A].lc].fa = A; if(t[A].rc) t[t[A].rc].fa = A; t[A].fa = 0; return A; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++){ scanf("%d", &t[i].w); f[i] = i; } scanf("%d", &m); while(m--){ int a, b; scanf("%d %d", &a, &b); int fa = find(a), fb = find(b); if(fa == fb) printf("-1\n"); else{ int A = fa, B = fb, ra, rb, r1, r2, r3; while(t[A].fa) A = t[A].fa; while(t[B].fa) B = t[B].fa; t[A].w /= 2; t[B].w /= 2; ra = merge(t[A].lc, t[A].rc); rb = merge(t[B].lc, t[B].rc); t[A].lc = t[A].rc = t[B].lc = t[B].rc = 0; r1 = merge(ra, rb); r2 = merge(r1, A); r3 = merge(r2, B); f[fa] = fb; printf("%d\n", t[r3].w); } } return 0; }
相关文章推荐
- LeakCanary 中文使用说明
- Maven库
- java与C++在数组处理上的区别
- STM32F4 输入输出(GPIO)模式理解
- STM32F4 输入输出(GPIO)模式理解
- 自动化测试总结
- IOS学习之Foundation框架—结构体
- hdu2099
- 《程序员面试笔试宝典》.(何昊,叶向阳) 版 学习记录
- go language
- 消息推送Comet介绍
- STM32F4 输入输出(GPIO)模式理解
- 多校第九场 1004 hdu 5399 Too Simple(贪心)
- 无人机
- STM32F4 输入输出(GPIO)模式理解
- 开发笔记:用Owin Host实现脱离IIS跑Web API单元测试
- oracle数据库创建序列,主键自动增1的代码
- Shell编程之条件判断与流程控制
- centos 7 epel 163 yum 源
- 按之字形顺序打印二叉树