hdu1512 & zoj2334Monkey King (左偏树 + 并查集(非优化的朴素并查集))
2015-07-28 21:30
405 查看
在一个森林里住着N(N<=10000)只猴子。
在一开始,他们是互不认识的。但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识(认识具有传递性)的两群猴子之间(可能只有他们自己)。
争斗时,两群猴子都会请出他们里面最强壮的一只(有可能是他自己)进行争斗。
争斗后,这两群猴子就互相认识。
每个猴子有一个强壮值,但是被请出来的那两只猴子进行争斗后,他们的强壮值都会减半(例如10会减为5,5会减为2)。
现给出每个猴子的初始强壮值,给出M次争斗,
如果争斗的两只猴子不认识,那么输出争斗后两只猴子的认识的猴子里最强壮的猴子的强壮值,否则输出-1。
hdu http://acm.hdu.edu.cn/showproblem.php?pid=1512
zoj http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2334
左偏树入门详见讲义,要先看看讲义理解理解左偏树的实现,下载链接
http://download.csdn.net/detail/hnust_taoshiqian/8941099
在一开始,他们是互不认识的。但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识(认识具有传递性)的两群猴子之间(可能只有他们自己)。
争斗时,两群猴子都会请出他们里面最强壮的一只(有可能是他自己)进行争斗。
争斗后,这两群猴子就互相认识。
每个猴子有一个强壮值,但是被请出来的那两只猴子进行争斗后,他们的强壮值都会减半(例如10会减为5,5会减为2)。
现给出每个猴子的初始强壮值,给出M次争斗,
如果争斗的两只猴子不认识,那么输出争斗后两只猴子的认识的猴子里最强壮的猴子的强壮值,否则输出-1。
hdu http://acm.hdu.edu.cn/showproblem.php?pid=1512
zoj http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2334
左偏树入门详见讲义,要先看看讲义理解理解左偏树的实现,下载链接
http://download.csdn.net/detail/hnust_taoshiqian/8941099
#include<cstdio> #include<iostream> #include<algorithm> #include<vector> #include<cstring> #define MT(x,i) memset(x,i,sizeof(x)) using namespace std; const int maxn=100000+10; int tot,v[maxn],l[maxn],r[maxn],d[maxn],fa[maxn]; ///value,left,right,dist(到最近外点的距离(外点:没有两个儿子的点)) int Merge(int x,int y){ if(x==y) return x; if(!x) return y; if(!y) return x; if(v[x]<v[y]) swap(x,y);///保证x>y。根最大 r[x]=Merge(r[x],y); fa[r[x]]=x;///更新父亲 if(d[l[x]]<d[r[x]]) swap(l[x],r[x]);///左子树距离大于右子树 d[x]=d[r[x]]+1; return x; } int Init(int x){ v[tot]=x; l[tot]=r[tot]=d[tot]=0; return tot++; } int Insert(int x,int y){///向编号为x的左偏数中插入权值为y的节点 return Merge(x,Init(y)); } int Top(int x){ return v[x]; } int Pop(int x){ fa[l[x]]=l[x]; fa[r[x]]=r[x]; return Merge(l[x],r[x]); } int Find(int x){ while(fa[x]!=x) x=fa[x]; return x; } void init0(){ MT(l,0);MT(r,0);MT(d,0); tot=1; } int main() { int n,m,x,y; while(~scanf("%d",&n)){ init0(); for(int i=1;i<=n;i++){ scanf("%d",&v[i]); fa[i]=i; } for(scanf("%d",&m);m--;){ scanf("%d%d",&x,&y); int fx=Find(x),fy=Find(y); if(fx==fy){puts("-1");continue;}///认识 int rt=Pop(fx);///x树的根,也是最大值 v[fx]/=2;l[fx]=r[fx]=d[fx]=0; fx=Merge(rt,fx); rt=Pop(fy);///y树的根,也是最大值 v[fy]/=2;l[fy]=r[fy]=d[fy]=0; fy=Merge(rt,fy); if(v[fx]>v[fy]) printf("%d\n",v[fx]); else printf("%d\n",v[fy]); Merge(fx,fy); } } return 0; }
相关文章推荐
- 杭电 1896 Stones 队列 附题目翻译
- Catch That Cow 寻找那头牛
- [c]sdnuoj 1031 拓扑排序
- 云计算 杂谈
- 关于拓扑排序
- Struts2中result配置中常见的几种视图转发类型
- 网站高并发大流量访问的处理及解决方法
- 《Node web开发》笔记
- 流程控制之if、多重if、嵌套
- 网格中矩形的个数
- (转)云计算 杂谈
- 暑假集训 第三周 STL I - Web Navigation网页导航
- 黑马程序员——高新技术---Java基础-IO流_File类,递归思想
- HDU 5317 RGCDQ
- 舞蹈链 - Sudoku
- iOS的文件管理——沙盒(sandbox)
- Lift Hopping (Uva 10801 最短路)
- Qt窗口中的一些小技术总结
- cocos2d小游戏---忍者吃西瓜
- 图结构练习——最小生成树