zoukankan      html  css  js  c++  java
  • 左偏堆

    左偏堆,顾名思义就是向左偏的堆,也就是左边特别重的堆。

    左偏堆是一种可并堆,其实现的基本操作是,合并,删除,插入(就是与一个只有一个节点的左偏堆合并)

    合并操作

     1 int merge(int a,int b){
     2     if (a==0) return b;
     3     if (b==0) return a;
     4     if (heap[a].v<heap[b].v) swap(a,b);
     5     heap[a].r=merge(heap[a].r,b);
     6     heap[heap[a].r].f=a;
     7     if(heap[heap[a].l].dis<heap[heap[a].r].dis) swap(heap[a].l,heap[a].r);
     8     if(heap[a].r==0) heap[a].dis=0;
     9     else heap[a].dis=heap[heap[a].r].dis+1;
    10     return a;
    11 }
    合并

    删除操作

    删除掉最上面的节点,并把其左右儿子合并

    1 int pop(int a){
    2     int l=heap[a].l;
    3     int r=heap[a].r;
    4     heap[l].f=l;
    5     heap[r].f=r;
    6     heap[a].l=heap[a].r=heap[a].dis=0;
    7     return merge(l,r);
    8 }
    删除

    以下为例题

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2334

     1 #include<cstdio>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 struct tree{
     7     int l,r,v,f,dis;
     8 } heap[100005];
     9 
    10 int merge(int a,int b){
    11     if (a==0) return b;
    12     if (b==0) return a;
    13     if (heap[a].v<heap[b].v) swap(a,b);
    14     heap[a].r=merge(heap[a].r,b);
    15     heap[heap[a].r].f=a;
    16     if(heap[heap[a].l].dis<heap[heap[a].r].dis) swap(heap[a].l,heap[a].r);
    17     if(heap[a].r==0) heap[a].dis=0;
    18     else heap[a].dis=heap[heap[a].r].dis+1;
    19     return a;
    20 }
    21 
    22 int pop(int a){
    23     int l=heap[a].l;
    24     int r=heap[a].r;
    25     heap[l].f=l;
    26     heap[r].f=r;
    27     heap[a].l=heap[a].r=heap[a].dis=0;
    28     return merge(l,r);
    29 }
    30 
    31 int find(int a){
    32     return heap[a].f==a?a:find(heap[a].f);
    33 }
    34 
    35 void read(int &x){
    36     char ch;
    37     x=0;
    38     ch=getchar();
    39     while (!(ch>='0'&&ch<='9')) ch=getchar();
    40     while ((ch>='0'&&ch<='9')) {
    41         x=x*10+ch-'0';
    42         ch=getchar();
    43     }
    44 }
    45 
    46 int main(){
    47     int i,a,b,finda,findb,n,m;
    48     while (scanf("%d",&n)==1){
    49         for (int i=1;i<=n;i++){
    50             read(heap[i].v);
    51             heap[i].l=heap[i].r=heap[i].dis=0;
    52             heap[i].f=i;
    53         }
    54         read(m);
    55         while(m--){
    56             read(a);read(b);
    57             finda=find(a);
    58             findb=find(b);
    59             if(finda==findb) printf("-1
    ");
    60             else{
    61                 heap[finda].v/=2;
    62                 int u=pop(finda);
    63                 u=merge(u,finda);
    64                 heap[findb].v/=2;
    65                 int v=pop(findb);
    66                 v=merge(v,findb);
    67                 printf("%d
    ",heap[merge(u,v)].v);
    68             }
    69         }
    70     } 
    71     return 0;
    72 }

    最后是论文

    http://wenku.baidu.com/link?url=t55yGX-UkUdEXBhpvBwuzjKP16F7lFl0RKSVVBBW5zXWRB7rRXvLLj1jM-pzhbH834hQl0KKT4va247VmSepsGDSrYF1E3le_WpnKc2xfCi

  • 相关阅读:
    [结题报告]10235 Simply Emirp Time limit: 3.000 seconds
    [杭电ACM]1720A+B Coming
    [结题报告]10041 Vito's Family Time limit: 3.000 seconds
    mysqlvarchar、text 类型到底能存储多大字符?
    mysql项目更换数据源为oralce后项目调整
    Oracle创建定时任务执行函数
    IOS手机访问网页window.location.href跳转新页面第一次可以第二次报错失效
    logrotate日志分割
    查找一批设备的在线情况
    pkill 用法例子
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5087156.html
Copyright © 2011-2022 走看看