ZOJ 2334 HDU 1512 Monkey King

来源:互联网 发布:telnet 发送字符 端口 编辑:程序博客网 时间:2024/04/30 12:58

题意:

猴子们打架  认识的猴子不会打架  两只猴子打完以后就认识了  A认识B B认识C A也认识C  每次打架由两伙猴子进行  分别选出自己的最高战斗力  在战斗之后两只猴子战斗力减半  给出m次打架  输出打架后这一伙猴子里的最强战斗力


思路:

判断两只猴子是不是一伙的  用到并查集

快速找出一伙猴子中的最强战斗力用到堆  但打完架两伙猴子合并时堆需要nlogn复杂度  因此用左偏树代替堆


代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 100010int n,m,tot;int fa[N];struct node{    int v,l,r,dis;}nd[N];int getf(int x){    if(x!=fa[x]) fa[x]=getf(fa[x]);    return fa[x];}int newnode(int x){    nd[tot].v=x;    nd[tot].l=0;    nd[tot].r=0;    nd[tot].dis=0;    tot++;    return tot-1;}int merge(int x,int y){    if(!x) return y;    if(!y) return x;    if(nd[x].v<nd[y].v) swap(x,y);    nd[x].r=merge(nd[x].r,y);    if(nd[nd[x].l].dis<nd[nd[x].r].dis) swap(nd[x].l,nd[x].r);    nd[x].dis=nd[nd[x].r].dis+1;    return x;}int pop(int x){    int tmp=merge(nd[x].l,nd[x].r);    nd[x].dis=nd[x].l=nd[x].r=0;    return tmp;}int main(){    int i,j,fi,fj,x;    while(~scanf("%d",&n))    {        tot=1;        for(i=1;i<=n;i++)        {            scanf("%d",&j);            fa[i]=newnode(j);        }        scanf("%d",&m);        while(m--)        {            scanf("%d%d",&i,&j);            fi=getf(i);            fj=getf(j);            if(fi==fj) puts("-1");            else            {                i=pop(fi);                nd[fi].v/=2;                j=pop(fj);                nd[fj].v/=2;                i=merge(i,j);                i=merge(i,fi);                i=merge(i,fj);                fa[i]=fa[fi]=fa[fj]=i;                printf("%d\n",nd[i].v);            }        }    }    return 0;}


0 0
原创粉丝点击