码迷,mamicode.com
首页 > 其他好文 > 详细

Monkey King(可并堆)

时间:2019-08-03 01:12:09      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:直接   题解   pre   swa   close   lap   alt   else   就会   

题意

有n只猴子,一开始互不认识,每次有两只猴子要打架,他们会找来自己认识的最厉害的猴子来帮他们打(然而他们就看戏),打完后打架的猴子(不是看戏的)武力值会减少一半(下取整),并且他们也互相认识了,在这时询问他们认识的猴子中最厉害的猴子的武力值,打架的在之前认识输出-1。

n,m<=100000

题解

直接用可并堆就好了,对于打完认识就是合并两个队伍,但是对于武力值减少怎么弄?

就直接把老大踢出去,再重新来过。具体实现就是把老大的ls,rs合并,这样他就出来了,然后再合并他和ls(rs)的堆。

具体实现的时候有一些细节,在代码里面实现。

技术图片
#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int n,m,a[maxn];
int fa[maxn],ls[maxn],rs[maxn],dis[maxn],val[maxn];

int find(int x){
  return fa[x]==x ? x : find(fa[x]);
}

int merge(int A,int B){
  if(!A) return B;
  if(!B) return A;
  if(val[A]<val[B]) swap(A,B);
  rs[A]=merge(rs[A],B);
  fa[rs[A]]=A;
  if(dis[rs[A]]>dis[ls[A]]) swap(rs[A],ls[A]);
  if(!rs[A]) dis[A]=0;
  else dis[A]=dis[rs[A]]+1;
  return A;
}

int pop(int x){//int 是因为不改变ls,rs的话合并x可能他是叶子节点,就会RE
  fa[ls[x]]=ls[x];
  fa[rs[x]]=rs[x];
  fa[x]=x;
  int ret=merge(ls[x],rs[x]);
  ls[x]=rs[x]=0;//求出上面才能改
  return ret;
}

int main(){
  //freopen("testdata.in","r",stdin);
  while(scanf("%d",&n)!=EOF){
    for(int i=1;i<=n;i++){
      scanf("%d",&val[i]);
      fa[i]=i;
      ls[i]=rs[i]=dis[i]=0;
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
      int x,y;
      scanf("%d%d",&x,&y);
      int dx=find(x),dy=find(y);
      if(dx==dy){printf("-1\n");continue;}
      //printf("*--------%d %d------------*\n",dx,dy);
      int xx=pop(dx),yy=pop(dy);
      //printf("*---------%d %d------*\n",xx,yy);
      val[dx]>>=1;
      val[dy]>>=1;
      merge(dx,find(xx));
      merge(dy,find(yy));
      merge(find(dx),find(dy));
      //for(int j=1;j<=n;j++) printf("%d ",fa[j]);
      //putchar(10);
      printf("%d\n",val[find(dx)]);
    }
  }
  return 0;
}
View Code

 

Monkey King(可并堆)

标签:直接   题解   pre   swa   close   lap   alt   else   就会   

原文地址:https://www.cnblogs.com/sto324/p/11291530.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!