zoukankan      html  css  js  c++  java
  • 左偏树(转)

    1左偏树(Leftist Tree)是一种可并堆(Mergeable Heap) ,它除了支持优先队列的三个基本操作(插入,删除,取最小节点),还支持一个很特殊的操作——合并操作。
     
    2左偏树是一棵堆有序(Heap Ordered)二叉树。
     
    3左偏树满足左偏性质(Leftist Property)。
    [性质1] 节点的键值小于或等于它的左右子节点的键值。

    [性质2] 节点的左子节点的距离不小于右子节点的距离。

    [性质3] 节点的左子节点右子节点也是一颗左偏树。

     
    合并操作的代码如下:
    Function Merge(A, B)
        If A = NULL Then return B
        If B = NULL Then return A
        If key(B) < key(A) Then swap(A, B)
        right(A) ← Merge(right(A), B)
        If dist(right(A)) > dist(left(A)) Then
            swap(left(A), right(A))
        If right(A) = NULL Then dist(A) ← 0
        Else dist(A) ← dist(right(A)) + 1
        return A
    End Function

    hdoj 1512 Monkey King

    #include <iostream>
    #include <vector>
    using namespace std;
     
    const int maxn = 100005;
     
     
    struct tree {
        int l, r, v, dis, f;
    }heap[maxn];
     
     
    int merge( int a, int b ) {
        if( a == 0 ) return b;
        if( b == 0 ) return a;
        if( heap[a].v < heap[b].v ) swap( a, b );
        heap[a].r = merge( heap[a].r, b );
        heap[heap[a].r].f = a;
        if( heap[heap[a].l].dis < heap[heap[a].r].dis ) swap( heap[a].l, heap[a].r );
        if( heap[a].r == 0 ) heap[a].dis = 0;
        else heap[a].dis = heap[heap[a].r].dis + 1;
        return a;
    }
     
     
    int pop( int a ) {
        int l = heap[a].l;
        int r = heap[a].r;
        heap[l].f = l;
        heap[r].f = r;
        heap[a].l = heap[a].r = heap[a].dis = 0;
        return merge(l, r);
    }
     
     
    int find( int a ) { return heap[a].f == a ? a : find( heap[a].f ) ; }
     
    void Read( int &x ) {
        char ch;
        x = 0;
        ch = getchar();
        while( !(ch >= '0' && ch <= '9') ) ch = getchar();
        while( ch >= '0' && ch <= '9' ) {
            x = x * 10 + ch - '0' ;
            ch = getchar();
        }
    }
     
         
    int main() {
    //  freopen( "c:/aaa.txt", "r", stdin );
        int i, a, b, finda, findb, n, m;
        while( scanf( "%d", &n ) == 1 ) {
            for( i=1; i<=n; ++i ) {
                Read(heap[i].v);
                //scanf( "%d", &st[i].v );
                heap[i].l = heap[i].r = heap[i].dis = 0;
                heap[i].f = i;
            }
             
            //scanf( "%d", &m );
            Read( m );
            while( m-- ) {
                //scanf( "%d %d", &a, &b );
                Read( a ); Read( b );
                finda = find( a );
                findb = find( b );
                if( finda == findb ) {
                    printf("-1 ");
                } else {
                    heap[finda].v /= 2;
                    int u = pop( finda );
                    u = merge( u, finda );
     
                    heap[findb].v /= 2;
                    int v = pop( findb );
                    v = merge( v, findb );
     
                    printf( "%d ", heap[merge( u, v )].v );
                }
            }  
        }
        return 0;
    }
  • 相关阅读:
    20160419—JS备忘:服务器回发刷新页面提示重试的解决方案。
    JS备忘--子父页面获取元素属性、显示时间,iframe之间互相调用函数
    20160215--获取页面的高度和宽度
    20151013--设计模式六大原则(转载)
    20150915--文件下载
    20150909—Win10系统80端口被System占用
    GridView中实现CheckBox的全选
    Invoke和BeginInvoke的区别(转载)
    AJAX+图像验证码(一般处理程序)
    报表
  • 原文地址:https://www.cnblogs.com/gongpixin/p/6734927.html
Copyright © 2011-2022 走看看