• zoj 2334 Monkey King 左偏树+并查集


    题意:有一群猴子,每一只有一定的强壮值

    刚开始,每个人都不认识别人

    有m次争吵

    若x,y争吵

    如果 x认识y 输出-1

    如果x不认识y 则x认识的猴子中(包括自己)当前强壮值最大的和y认识的猴子中(包括自己)当前强壮值最大的决斗

    决斗完之后,决斗的两只猴子,强壮值减半(10->5,5->2) 且x认识的猴子和y认识的猴子都相互认识了 输出其中当前强壮值的最大值

    多组数据

    思路:左偏树

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 #define MAXN 100000+100
     8 struct node
     9 {
    10     int num,NPL;
    11     int left,right;
    12 };
    13 node tree[MAXN];
    14 int n,m;
    15 int f[MAXN],root[MAXN];
    16 int find(int x)
    17 {
    18     return f[x]==-1? x:f[x]=find(f[x]);
    19 }
    20 int Union(int x,int y)
    21 {
    22     f[find(x)]=find(y);
    23 }
    24 int merge(int x,int y)
    25 {
    26     if(x==0) return y;
    27     if(y==0) return x;
    28     if(tree[y].num>tree[x].num) 
    29         swap(x,y);
    30     tree[x].right=merge(tree[x].right,y);
    31 
    32     if(tree[tree[x].left].NPL<tree[tree[x].right].NPL)
    33         swap(tree[x].left,tree[x].right);
    34 
    35     if(tree[x].right==0) tree[x].NPL=0;
    36     else 
    37         tree[x].NPL=tree[tree[x].right].NPL+1;
    38     return x;
    39 }
    40 
    41 int solve(int x,int y)
    42 {
    43     if(find(x)==find(y)) return -1;
    44     int root_x=root[find(x)],root_y=root[find(y)];
    45     tree[root_x].num/=2; tree[root_y].num/=2;
    46 
    47     int tmp_x=merge(tree[root_x].left,tree[root_x].right);
    48     tree[root_x].left=tree[root_x].right=tree[root_x].NPL=0;
    49     tmp_x=merge(tmp_x,root_x);
    50 
    51     int tmp_y=merge(tree[root_y].left,tree[root_y].right);
    52     tree[root_y].left=tree[root_y].right=tree[root_y].NPL=0;
    53     tmp_y=merge(tmp_y,root_y);
    54 
    55     Union(x,y);
    56     root[find(x)]=merge(tmp_x,tmp_y);
    57     //cout<<tree[tmp_x].num<<" "<<tree[tmp_y].num<<" "<<y<<endl;
    58     return tree[root[find(x)]].num;
    59 }
    60     
    61 int main()
    62 {
    63     int i,x,y;
    64     while(scanf("%d",&n)!=EOF)
    65     {
    66         memset(tree,0,sizeof(tree));
    67         memset(f,0xff,sizeof(f));
    68         for(i=1;i<=n;i++) root[i]=i;
    69         for(i=1;i<=n;i++)
    70             scanf("%d",&tree[i].num);
    71         scanf("%d",&m);
    72         while(m--)
    73         {
    74             scanf("%d%d",&x,&y);
    75             printf("%d\n",solve(x,y));
    76         }
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    洛谷 P3355 骑士共存问题
    Redis 安装
    Java 集合:(十八) Map接口
    并发编程——Java版【目录】
    Java 集合:(十七) Queue 常用接口:BlockingQueue 子接口
    Java 集合:(十六) Queue 常用接口:Deque 子接口
    Java 集合:(十五) Queue 子接口
    Java 集合:(番外篇一) ArrayList线程不安全性
    第十三章:StringTable
    Java 集合:(十三) Set实现类:LinkedHashSet
  • 原文地址:https://www.cnblogs.com/myoi/p/2509126.html
Copyright © 2020-2023  润新知