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

左偏堆

时间:2015-12-29 22:26:43      阅读:325      评论:0      收藏:0      [点我收藏+]

标签:

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

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

合并操作

技术分享
 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\n");
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\n",heap[merge(u,v)].v);
68             }
69         }
70     } 
71     return 0;
72 }

最后是论文

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

 

左偏堆

标签:

原文地址:http://www.cnblogs.com/wuminyan/p/5087156.html

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